Вставьте текст в цикл while (1) для texteditor в 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). Почему это поведение? Что я делаю неправильно?

Благодарю.

0

Решение

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

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

Вместо того чтобы использовать бесконечный цикл, если вы хотите выполнить что-то как можно чаще, вы можете использовать QTimer и установить его интервал свойство 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();
}
4

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]