如何使用 QTimer 每 10 秒打印一条消息到 QTextBrowser?

发布于 2024-10-11 23:08:50 字数 745 浏览 7 评论 0原文

我已经为此工作了几个小时,但无法弄清楚,也无法在网上找到任何有效的帮助。基本上,我想要完成的要点是拥有一个带有按钮和 QTextBrowser 的 Qt GUI。当我按下按钮时,我希望它显示一条消息,然后每 10 秒打印一次该消息。

我想我会使用 QTimer,因为有一个计时器每 10 秒显示一次消息是有意义的。当我最初将其实现到我的“buttonClicked() SLOT”中时,它导致程序冻结。我在网上寻找解决方案并找到了 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() while循环,但它不会简单地停留在那里。

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

必须有一个简单的方法来做到这一点,但我对 Qt 的记录一直是

I have working at this for hours and cannot figure it out nor can I find any help online that works. Basically the gist of what I am trying to accomplish is to have a Qt GUI with a button and a QTextBrowser. When I push the button I want it to display a message and then keep printing this message every 10 seconds.

I figured I would use QTimer because it makes sense to have a timer to display the message every 10 seconds. When I originally implemented this into my `buttonClicked() SLOT it caused the program to freeze. I looked online for a solution and found QApplication::processEvents().

So basically in my function I had something like this:

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

   while(timer.isActive())
   {
      QApplication::processEvents() 
   }
}

I figured it would break out of the timer.isActive() while loop but it won't it simply stays in there.

So I figured this is a threading issue. So I figured out how to use QThreads but I still can't get it to work. Basically when I create a thread with a timer on it and the thread tells the timer to start, the program closes and the console says "The program has unexpectedly finished".

There has to be an easy way to do this but my track record with Qt has always been that th

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

千紇 2024-10-18 23:08:51

默认情况下,QTimer 将在每个时间间隔触发,直到您停止它。这就是为什么 timer.isActive() 始终为 true。使用timer.setSingleShot(true) 使计时器仅触发一次。 (或者使用 @tibur 的帖子中的 QTimer::singleShot 。)

By default, QTimer will fire every interval until you stop it. That's why timer.isActive() is always true. Use timer.setSingleShot(true) to make the timer fire only once. (Or use QTimer::singleShot as in @tibur's post.)

随风而去 2024-10-18 23:08:51

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

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

I thought the OP wanted to display the message repeatedly every 10secs?

In which case simply create a timer, connect an updateDisplay() function slot with the timer signal and start the timer.

等风来 2024-10-18 23:08:50

如果您想将消息显示 10 秒,更好的方法是在应用程序中创建一个插槽来删除该消息。然后,在您单击的按钮插槽中,添加您的消息并初始化一个计时器,该计时器将在 10 秒内触发您的删除消息插槽:

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

此外,那里不需要线程...

If you want to display your message for 10s, the better way to do that, is to create a slot in your application that will erase the message. Then, in your button clicked slot, add your message and initialize a timer which will trigger your remove message slot in 10s:

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

Also, there is no need for a thread there...

殤城〤 2024-10-18 23:08:50

您的代码有很多问题 - 我认为它本质上是伪代码,因为 timer 不存在以及类似的事情。

查看QTimer 参考。它有一个示例:

 QTimer *timer = new QTimer(this);
 connect(timer, SIGNAL(timeout()), this, SLOT(update()));
 timer->start(1000);

基本上,您想要创建一个附加插槽,然后将其连接到 timeout 信号并启动计时器。计时器会滴答作响,每一秒都会调用槽。在您的情况下,您可以将 1000 更改为 10000

如果这不起作用,您遇到的问题到底是什么?我不明白你为什么要使用线程,除非你无论如何都需要它们。

编辑查看您的更新,您说您想等待 10 秒钟。与其忙着等待,为什么不继续执行槽中的程序(由 singleShot 调用)呢?我认为你错过了一些 Qt 哲学......

Your code has many problems - I assume it's pseudocode, essentially, since timer doesn't exist and things like that.

Check out the QTimer reference. It has an example:

 QTimer *timer = new QTimer(this);
 connect(timer, SIGNAL(timeout()), this, SLOT(update()));
 timer->start(1000);

Basically, you want to make a slot that appends, then connect it to the timeout signal and start the timer. The timer will tick along and every second will call the slot. In your case, you'd change 1000 to 10000

If this isn't working, what exactly is the problem you're having? I don't understand why you're using threads, unless you need them anyway.

EDIT Looking at your update, you say that you want to wait for 10 seconds. Instead of busy-waiting, why not continue the program in your slot (called by singleShot)? I think you're missing some of the Qt philosophy...

残龙傲雪 2024-10-18 23:08:50

像这样组织你的程序会更好:

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

It will be better to organize your program like this:

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_;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文