Как использовать QTimer для печати сообщения в QTextBrowser каждые 10 секунд? - PullRequest
6 голосов
/ 14 января 2011

Я работаю над этим часами, не могу понять и не могу найти какую-либо помощь в сети, которая работает. По сути, суть того, чего я пытаюсь достичь, это иметь графический интерфейс Qt с кнопкой и QTextBrowser. Когда я нажимаю кнопку, я хочу, чтобы она отображала сообщение, а затем продолжала печатать это сообщение каждые 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 всегда был таким:

Ответы [ 5 ]

7 голосов
/ 14 января 2011

Если вы хотите, чтобы ваше сообщение отображалось в течение 10 секунд, лучший способ сделать это - создать в вашем приложении слот, который будет стирать сообщение.Затем, в щель, которую вы нажали кнопкой, добавьте ваше сообщение и инициализируйте таймер, который запустит ваш слот удаления сообщений через 10 с:

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

Кроме того, там нет необходимости в потоке ...

4 голосов
/ 15 января 2011

Будет лучше организовать вашу программу так:

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_;
}
4 голосов
/ 14 января 2011

У вашего кода много проблем - я предполагаю, что это псевдокод, по сути, поскольку timer не существует и тому подобное.

Проверьте ссылку QTimer.У него есть пример:

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

По сути, вы хотите создать добавляемый слот, затем подключить его к сигналу timeout и запустить таймер.Таймер включится, и каждая секунда вызовет слот.В вашем случае вы бы изменили 1000 на 10000

Если это не сработало, с какой именно проблемой вы столкнулись?Я не понимаю, почему вы используете потоки, если вам все равно они не нужны.

РЕДАКТИРОВАТЬ Глядя на свое обновление, вы говорите, что хотите подождать 10 секунд.Вместо того, чтобы ждать, почему бы не продолжить программу в вашем слоте (называемом singleShot)?Я думаю, что вам не хватает некоторой философии Qt ...

1 голос
/ 14 января 2011

Я думал, что ОП хочет отображать сообщение повторно каждые 10 секунд?

В этом случае просто создайте таймер, подключите слот функции updateDisplay () к сигналу таймера и запустите таймер.

1 голос
/ 14 января 2011

По умолчанию QTimer будет запускаться каждый интервал, пока вы не остановите его. Вот почему timer.isActive() всегда верно. Используйте timer.setSingleShot(true), чтобы таймер сработал только один раз. (Или используйте QTimer::singleShot как в сообщении @ tibur.)

...