編輯3:當我第一次問這個問題時,我以爲是因爲QTimer
只發射一次;但事實證明,這是因爲我基於它的remainingTime()
成員觀察它。原來實際問題是,remainingTime()
倒計數到0
只有一次(和timeout()
信號是確實發射多次)。非單星QTimer只倒計數一次
我有一個單線程Qt應用程序,它有一個需要重複調用的計時器。我還有一個進度條來顯示主定時器剩餘的時間,並且進度條每隔40ms由另一個定時器更新一次。
目前,主定時器設置爲15秒(15 x 1000 = 15000毫秒),但定時器僅觸發其一次事件QTimer::timeout()
。之後,remainingTime()
始終返回0
,即使isActive()
返回true
。 (isSingleShot()
回報false
,也是如此。)
下面是相關代碼:
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow),
interval_capture(15.00),
timer_capture(new QTimer(this)),
timer_updateProgress(new QTimer(this)),
isRecording(false)
{
ui->setupUi(this);
QObject::connect(timer_updateProgress, &QTimer::timeout,
this, &MainWindow::update_progress);
// I had to add the following line to force the timer to be called repeatedly
//QObject::connect(timer_capture, &QTimer::timeout,
// timer_capture, static_cast<void (QTimer::*)()>(&QTimer::start));
timer_capture->setInterval(static_cast<int>(round(interval_capture * 1000)));
timer_capture->setSingleShot(false);
timer_updateProgress->setInterval(40);
timer_updateProgress->setSingleShot(false);
}
// -snip-
void MainWindow::update_progress()
{
// The math does work
double time_passed =
static_cast<double>(interval_capture) -
static_cast<double>(timer_capture->remainingTime())/1000.0;
double fraction_passed =
time_passed/static_cast<double>(interval_capture);
int percentage = static_cast<int>(round(100 * fraction_passed));
ui->progressBar_timer->setValue(percentage);
// I only get an output of "tick: 0" after the first timeout
if (timer_capture->isSingleShot() || !timer_capture->isActive()) {
ui->progressBar_timer->setFormat("it ded");
} else {
ui->progressBar_timer->setFormat("tick: " + QString::number(timer_capture->remainingTime()));
}
}
// -snip-
void MainWindow::on_button_start_clicked()
{
isRecording = !isRecording;
switch (isRecording) {
case true :
ui->button_start->setIcon(QIcon(":/icons/stop.png"));
timer_capture->start();
timer_updateProgress->start();
break;
case false :
ui->button_start->setIcon(QIcon(":/icons/record.png"));
timer_capture->stop();
timer_updateProgress->stop();
break;
}
}
奇怪的是,我知道timer_updateProgress
確實工作(因爲我可以看到進度條更新),並以基本相同的方式初始化...
編輯:爲了澄清,我相信,我的所有其他邏輯是正常的,因爲我可以在調試器中看到:
timer_capture.isSingleShot()
是false
timer_capture.remainingTime()
是0
timer_capture.isActive()
是true
- 所有計算結果都是正確的(例如
time_passed
)
而且我還可以看到,倒計時一次,然後停止。
編輯2:我下面的代碼添加到update_progress()
年底進一步說明發生了什麼:
qDebug() << "Active: " << timer_capture->isActive();
qDebug() << "Single shot: " << timer_capture->isSingleShot();
qDebug() << "Remaining ticks:" << timer_capture->remainingTime() <<
"/" << timer_capture->interval() << "\n";
我得到的輸出是:
Active: true
Single shot: false
Remaining ticks: 1496/15000
Active: true
Single shot: false
Remaining ticks: 996/15000
Active: true
Single shot: false
Remaining ticks: 494/15000
Active: true
Single shot: false
Remaining ticks: 3/15000
Active: true
Single shot: false
Remaining ticks: 0/15000
Active: true
Single shot: false
Remaining ticks: 0/15000
(廣告無窮無盡)
你已經註釋掉了timer_capture-> timeout()的插槽。也許'QTimer'實際上沒有做任何事情,如果沒有插槽連接到它?如果它在連接插槽時開始工作,則看起來可能是正在發生的事情。 –
當插槽連接到'&MainWindow :: update_progress()'(未註釋)時,它不起作用,但當它連接到&QTimer :: start()時(如預期的那樣)它可以工作。 我試着將它連接到'update_progress()',因爲這會使它與'timer_updateProgress'基本相同。 –
我明白了。你可以簡化一個計時器,'timer_updateProgress'?只要讓它在每次暫停時增加一個進度條。你是在調試器中運行還是僅僅觀察UI的變化?在調試器中運行會有很大的幫助,所以你可以看到你的計算結果。 –