Multithreading 如何使用QTimer每隔10秒将消息打印到QTextBrowser?

Multithreading 如何使用QTimer每隔10秒将消息打印到QTextBrowser?,multithreading,qt,qt4,timer,qthread,Multithreading,Qt,Qt4,Timer,Qthread,我已经为此工作了好几个小时,弄不明白,也找不到任何在线帮助。基本上,我试图实现的要点是拥有一个带有按钮和QTextBrowser的Qt图形用户界面。当我按下按钮时,我希望它显示一条消息,然后每10秒打印一次该消息 我想我会使用QTimer,因为每10秒有一个计时器来显示消息是有意义的。当我最初在我的`buttonClicked()槽中实现它时,它导致程序冻结。我在线查找解决方案,发现QApplication::processEvents() 所以基本上在我的函数中,我有这样的东西: while(

我已经为此工作了好几个小时,弄不明白,也找不到任何在线帮助。基本上,我试图实现的要点是拥有一个带有按钮和
QTextBrowser
的Qt图形用户界面。当我按下按钮时,我希望它显示一条消息,然后每10秒打印一次该消息

我想我会使用QTimer,因为每10秒有一个计时器来显示消息是有意义的。当我最初在我的`buttonClicked()槽中实现它时,它导致程序冻结。我在线查找解决方案,发现QApplication::processEvents()

所以基本上在我的函数中,我有这样的东西:

while(1)
{
   QTimer *timer;
   connect(...)  //omitted parameters for this example     
   timer.start(10000);
   ui->diplay->append("Message");

   while(timer.isActive())
   {
      QApplication::processEvents() 
   }
}
我想它会在循环时中断timer.isActive(),但不会,它只是停留在那里

所以我认为这是一个线程问题。所以我想出了如何使用QThreads,但仍然无法让它工作。基本上,当我创建一个带有计时器的线程,线程告诉计时器开始时,程序关闭,控制台显示“程序意外完成”


必须有一个简单的方法来实现这一点,但我在Qt方面的记录一直是,如果您想显示消息10秒,更好的方法是在应用程序中创建一个插槽来擦除消息。然后,在单击按钮的插槽中,添加消息并初始化计时器,该计时器将在10秒内触发删除消息插槽:

QTimer::singleShot(10000, this, SLOT(eraseMessageSlot()));

另外,那里不需要线程…

您的代码有很多问题-我假设它本质上是伪代码,因为
计时器不存在,诸如此类的东西

查看
QTimer
参考资料。它有一个例子:

 QTimer *timer = new QTimer(this);
 connect(timer, SIGNAL(timeout()), this, SLOT(update()));
 timer->start(1000);
基本上,您需要制作一个附加的插槽,然后将其连接到
超时信号,然后启动计时器。计时器将滴答作响,每秒钟将调用插槽。在您的情况下,您需要将
1000
更改为
10000

如果这不起作用,你到底有什么问题?我不明白你为什么要用线程,除非你需要它们


编辑查看您的更新,您说您想等待10秒钟。与其忙着等待,为什么不在您的插槽中继续该程序(由
singleShot
调用)?我认为您缺少了一些Qt原理…

默认情况下,QTimer将在您停止之前触发每个间隔。这就是为什么
timer.isActive()
总是正确的。使用
timer.setSingleShot(true)
使计时器只启动一次。(或者像@tibur的帖子一样使用
QTimer::singleShot

我以为OP想要每10秒重复显示一次消息


在这种情况下,只需创建一个计时器,将updateDisplay()函数插槽与计时器信号连接,然后启动计时器。

最好按如下方式组织程序:

class MainWindow : QWidget //or any other parent class
{
public:
MainWindow()
{
    QPushButton *button = new QPushButton(this);
    browser_ = new QTextBrowser(this); //and some params maybe
    QVBoxLayout * layout = new QVBoxLayout(this); //can be used another layout
    layout->addWidget(button);
    layout->addWidget(browser_);

    connect(button, SIGNAL(pressed()),
        this, SLOT(onButtonPressed()));

    timer_ = new QTimer(this);
    connect(timer, SIGNAL(timeout()), 
        this, SLOT(timerHandler()));
    }
    ~MainWindow();

public slots:
    void onButtonPressed()
    {
        timerHandler(); //to display message when button is pressed
        if (!timer->isActive()) timer->start(TIMER_INTERVAL); //TIMER_INTERVAL = 10000;
    }
    void timerHandler()
    {
         //put your code to display message here
    }

private:
    QTextBrowser *browser_;
    QTimer *timer_;
}

这基本上就是我所拥有的。似乎我忘记了“this参数”,没有注意到。考虑到我在上面几行使用了connect语句,并使用了正确的参数,这真是太差劲了。出于某种原因,编译器没有对我大喊大叫。我认为我需要线程,因为它是冻结的,但显然我只是有一个不正确的连接。请查看我在OP中的更新。谢谢!更新:我现在使用timer->singleShot(定时器,信号(timeout()),这个,插槽(UPDATE());但我需要程序打印消息并等待10秒,然后继续处理。我把它放在一个while循环中,所以它一直在做单打,而不是每10秒一次。有什么建议吗?谢谢几乎所有人都忽略了这一事实,即这是在一段时间内发生的?难怪程序会冻结。这是Qt中应该采用的结构。每隔10秒,计时器将调用timerHandler函数。在该函数中,只需附加消息并退出该函数。简单直接,最重要的是,没有无限循环导致程序冻结。无论计时器是否处于活动状态,它都将调用timerHandler()。据我所知,计时器在这里什么也不做,只是在时间过去后自行复位。据我所知,这段代码只会在每次按下按钮时显示消息。当按钮被按下时,计时器会被激活;因为如果(!timer->isActive())timer->start(timer\u INTERVAL);将被称为