Вставить текст в цикле while(1) в текстовый редактор в QT

Я пытаюсь напечатать «Некоторый текст» в QTextBrowser непрерывно в течение «n» времени. Где «n» — целое число. Для этого я использовал QTimer::SingleShot для синхронизации. После срабатывания тайм-аута FLAG устанавливается в false, и этот «FLAG» отслеживается в цикле while, чтобы прерваться, когда FLAG имеет значение false, и он должен вставлять текст до тех пор, пока FLAG не будет установлен в FALSE. Начальное значение для FLAG истинно.

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QThread>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    FLAG = true;

}

void MainWindow::on_pushButton_clicked()
{
    ui->pushButton->setEnabled(false);
   RunTheTimer();
    int counter = 0;

    do
    {
        ui->textBrowser->insertPlainText(QString("Inside While loop %1 \n").arg(counter++));
        counter++;
    }while(FLAG);

    FLAG = true;

}
void MainWindow::RunTheTimer()
{
     ui->textBrowser-> insertPlainText("Timer Started");
    QTimer::singleShot(60000, this, SLOT(Update()));// One Minute

}

void MainWindow::Update()
{
   ui->textBrowser-> insertPlainText("Timeout signal triggered");
    ui->pushButton->setEnabled(true);
   FLAG = false;
}
MainWindow::~MainWindow()
{
    delete ui;
}

Приложение зависает, когда я нажимаю кнопку. После отладки я заметил, что тайм-аут не срабатывает после того, как выполнение вводится в цикл while (1), и приложение не может вставить какой-либо текст внутри цикла while (1). Почему такое поведение? Что я делаю не так?

Спасибо.


person learner    schedule 17.12.2016    source источник


Ответы (1)


Вы не возвращаете управление циклу событий, многие вещи в Qt не предназначены для работы без цикла событий. ="nofollow noreferrer">эта страница из вики Qt, в вашем случае:

  • QTextBrowser не сможет показать только что добавленный текст, поскольку для этого требуется, чтобы виджет мог получать события рисования (а это невозможно без цикла событий).
  • Таймер, который устанавливает ваш флаг в false, не сможет сработать, так как ваша программа всегда занята выполнением вашего цикла while, и она не сможет сделать ничего другого (если только он не выйдет из этого цикла while, а это невозможно, если он не установит ваш флаг в false...).

Вместо использования бесконечного цикла, если вы хотите выполнять что-то как можно чаще, вы можете использовать QTimer и установить его interval в 0, это специальное значение, которое приводит к тайм-ауту таймера, как только цикл обработки событий завершает обработку всех событий в очереди событий.

Используя описанный выше подход вместо бесконечного цикла, вы можете использовать другой таймер, чтобы остановить указанный выше таймер через определенное время, и вам не нужно беспокоиться о том, что события не прибывают, а таймеры не срабатывают, поскольку цикл событий всегда выполняется. Теперь.

Вот возможная реализация описанного выше подхода:

скриншот

#include <QtWidgets>

int main(int argc, char* argv[]){
    QApplication a(argc, argv);

    //set up GUI
    QWidget widget;
    QVBoxLayout layout(&widget);
    QTextBrowser textBrowser;
    QPushButton button("Add Text");
    layout.addWidget(&textBrowser);
    layout.addWidget(&button);

    //timer with 0 interval instead of while loop
    QTimer workTimer;
    workTimer.setInterval(0);
    int counter=0;
    QObject::connect(&workTimer, &QTimer::timeout, [&]{
        //add text to textBrowser whenever the workTimer fires
        textBrowser.append(QStringLiteral("Additional Text %1").arg(counter++));
    });
    //when the button is clicked
    QObject::connect(&button, &QPushButton::clicked, [&]{
        //start work timer
        workTimer.start();
        button.setEnabled(false);
        //stop work timer after 5 seconds
        QTimer::singleShot(5000, [&]{
            workTimer.stop();
            button.setEnabled(true);
        });
    });
    widget.show();

    return a.exec();
}
person Mike    schedule 17.12.2016
comment
Обратите внимание, что [&](){ ... } можно просто записать как [&]{ ... }. - person Kuba hasn't forgotten Monica; 19.12.2016