0

我试图将“一些文本”打印到 QTextBrowser,连续“n”时间。其中“n”是整数。为此,我使用 QTimer::SingleShot 进行计时。一旦触发超时,FLAG 设置为 false,并且在循环中监视此“FLAG”以在 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) 循环中插入任何文本,超时就不会触发。为什么会有这种行为?我究竟做错了什么?

谢谢。

4

1 回答 1

5

您没有将控制权返回给事件循环,Qt 中的许多事情都不能在没有事件循环的情况下工作,在您的情况下,请查看Qt wiki 中的此页面

  • QTextBrowser将无法显示新添加的文本,因为这需要小部件能够接收绘制事件(如果没有事件循环,这是不可能的)。
  • 将您的标志设置为 false 的计时器将无法触发,因为您的程序总是忙于执行您的while循环,并且它将无法做任何其他事情(除非它从该while循环中退出,并且这是不可能的,如果它不会将您的标志设置为假......)。

如果您想尽可能重复地执行某事,而不是使用无限循环,您可以使用 aQTimer并将其间隔属性设置为 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();
}
于 2016-12-17T11:49:08.287 回答