2016-12-17 7 views
0

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

#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; 
} 

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

Спасибо.

ответ

4

Вы не возвращая управление в цикл обработки событий, многие вещи в Qt не предназначены для работы без цикла событий, Посмотрите this page from the Qt wiki, в вашем случае:

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

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

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

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

screenshot

#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(); 
} 
+0

Хорошее объяснение, проблема решена – learner

+0

Обратите внимание, что '[&]() {...} 'могут быть просто записаны как '[&] {...}'. –

+0

@KubaOber, спасибо за заметку :) – Mike