Qt中的即时对象互通

时间:2014-08-02 18:13:21

标签: c++ qt

在这个简单的例子中,pushButton1_clicked()通过setText()方法改变QLabel的文本:

void MainWindow::pushButton1_clicked()
{
    ui->label1->setText("BLABLABLA");
    Sleep(5000);
}

此处,label1 Text将设置为“BLABLABLA”,但仅在pushButton1_clicked()完成后(5秒后)。为什么?我希望在调用setText()方法的同时更改它,然后线程才能睡5秒钟。怎么在Qt中完成?

提前致谢。

PS。将Qt 5.2与Visual Studio 2012编译器一起使用。

3 个答案:

答案 0 :(得分:3)

Sleep方法阻止GUI线程5秒钟。你应该永远不会阻止GUI线程。执行Sleep时,除了本机异步过程调用外,同一线程中的其他任何内容都不会运行。 setText方法只是计划小部件更新,它不会在那个时刻重新绘制小部件。由于Sleep阻止控件返回事件循环,因此不会发生计划的更新。

如果要在按下按钮后延迟执行某些任务,则应使用计时器:

class MainWindow : public QWidget {
  QScopedPointer<Ui::MainWindow> ui;
  ...
  Q_SLOT void pushButton1_clicked() {
    ui->label1->setText("Waiting...");
    QTimer::singleShot(5000, this, SLOT(postWait()));
  }
  Q_SLOT void postWait() {
    ui->label1->setText("Finished waiting.");
  }
public:
  MainWindow(QWidget * parent = 0) : QWidget(parent), ui(new Ui::MainWindow(this)) {}
  ~MainWindow() {} // The smart pointer will delete the child widgets automatically
};

答案 1 :(得分:2)

让我们考虑一下这里的运作顺序:

  • GUI为按钮按钮发出信号更改事件
  • 您的广告位已被调用
  • 在您的广告位中,您正在排队小部件更新事件
  • 然后暂停主事件循环5秒
  • 一旦执行返回主事件循环,它就可以更新屏幕

这是任何平台上任何类型的GUI的典型行为。锁定GUI线程被认为是不好的做法 - 用户不希望界面锁定。相反,您应该使用QTimer,它不会阻止主事件循环。

答案 2 :(得分:0)

这是我在stackoverflow中的第一个答案,我今天注册,所以请原谅我,如果我做错了什么。 睡眠冻结所有应用程序,因此您可以使用QTest :: qWait 例如

void MainWindow::on_pushButton_3_clicked()
{
    ui->label->setText("BLABLABLA"); //now we change the text
     //Sleep(5000);
    QTest::qWait(5000); //waiting, nothing happened
    qDebug() << "5 sec gone";//after 5 sec we can see this words
}