Qt C++双QTimer实现:计数与显示分离解决显示卡顿问题
Hey there! I see you're looking to split your timer logic into two separate QTimers to fix that laggy screen update—great approach! The core issue with your original code is that you're updating the UI every 500ms, which can cause unnecessary overhead and stuttering. By separating the counting (fast, background) from the UI display (slow, intentional), we'll keep things smooth while maintaining accurate timing.
Let's walk through the solution step by step:
Key Changes Needed
- Use a member variable for counting: Your current
countis a local variable, so it resets every time the slot runs—we need a persistent variable to track the actual count. - Split timer responsibilities:
- One timer (
timer) runs at 500ms to increment the count in the background (no UI operations here). - A second timer (
timer2) runs every 20 seconds (20000ms) to push the latest count to the LCD display.
- One timer (
- Fix signal-slot matching: Your original code has a case mismatch (
functionstart()vsfunctionStart()) which would break the connection—we'll use clearer names to avoid this.
Updated Code
First, Update mainwindow.h
We need to add our persistent count variable and declare the new slot for UI updates:
#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include <QTimer> QT_BEGIN_NAMESPACE namespace Ui { class MainWindow; } QT_END_NAMESPACE class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget *parent = nullptr); ~MainWindow(); private slots: void updateCount(); // Handles background counting void updateDisplay(); // Handles UI display update void on_pushButton_clicked(); private: Ui::MainWindow *ui; QTimer *timer; QTimer *timer2; int m_count; // Persistent count variable }; #endif // MAINWINDOW_H
Now, Update mainwindow.cpp
Here's the corrected implementation with dual timers:
#include "mainwindow.h" #include "ui_mainwindow.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) , m_count(0) // Initialize count to 0 { ui->setupUi(this); // Initialize timers and parent them to MainWindow for auto-cleanup timer = new QTimer(this); timer2 = new QTimer(this); // Connect timers to their respective slots (using type-safe new syntax) connect(timer, &QTimer::timeout, this, &MainWindow::updateCount); connect(timer2, &QTimer::timeout, this, &MainWindow::updateDisplay); // Show initial count immediately so users don't see a blank LCD ui->lcdNumber->display(m_count); } // Background counting logic - no UI operations here, runs every 500ms void MainWindow::updateCount() { m_count++; } // UI update logic - only runs every 20 seconds to avoid lag void MainWindow::updateDisplay() { ui->lcdNumber->display(m_count); } MainWindow::~MainWindow() { delete ui; // Timers are parented to MainWindow, so they'll be automatically deleted } void MainWindow::on_pushButton_clicked() { if(timer->isActive()){ // Stop both timers when pausing timer->stop(); timer2->stop(); ui->pushButton->setText("Start"); } else { // Start the fast counting timer timer->start(500); // Start the slow display update timer timer2->start(20000); // Immediately update the display when starting (no 20-second wait!) updateDisplay(); ui->pushButton->setText("Stop"); } }
Why This Works
- No more UI lag: We're only updating the LCD every 20 seconds instead of every 500ms, which drastically reduces UI thread overhead.
- Accurate counting: The background timer still ticks every 500ms to keep the count precise.
- Better user experience: We show the initial count immediately and update it right when starting, so users don't wait 20 seconds to see the first number.
A quick side note: I switched to Qt's new signal-slot syntax (&QTimer::timeout instead of SIGNAL(timeout())) because it's type-safe and catches errors at compile time—highly recommended over the old string-based syntax!
内容的提问来源于stack exchange,提问作者süslü coder

