窗口无效时Qt内存泄漏和CPU过载

时间:2015-12-11 02:39:33

标签: c++ qt memory-leaks

我有一个Qt应用程序,它使用paintEvent显示和更新许多ui元素(标签,自定义小部件,进度条和绘图)。要设置更新的数值,我使用

void slotUpdateUI()
{
  ui->label_stateX->setText( QString::number(worker->m_stateX,'f',2 )  );
  ui->customWidget->m_cur = (int) worker->m_val; // m_cur is used by the widget's paintEvent()

}
使用slotUpdateUI()定期触发

update()以及QTimer

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

运行应用程序时的CPU负载和内存大约是。 60%和67MB。 (没有工作人员运行,它是50%和60MB,仅适用于UI)。这些数字保持不变。只要窗口处于活动状态(在前台),就会一样。

但是,当窗口变为非活动状态时(例如,通过在前台打开浏览器或取景器),CPU负载和内存迅速增加,在1分钟内远高于100%和100MB。

当我重新激活窗口时,UI会冻结2-3秒,然后取消冻结,CPU负载和内存将恢复到原始值50%和60%。

我发表评论

时不会发生此问题
// connect( timer, SIGNAL( timeout() ), this, SLOT( update() ) );

我的问题是:

  1. 为什么CPU首先加载很高(50-60%只是用大约40个元素(主要是标签)来更新UI)。这是一个通常的数字吗?

  2. 当窗口处于非活动状态时(在后台),导致CPU过载和内存泄漏的原因是什么?

  3. 我在2014年的macbook pro上工作。

    感谢您的任何建议!

    ========== ADDENDUM:==========

    这里是完整的源代码: https://www.dropbox.com/s/c90fg15s97mg9nw/OcGui.zip?dl=0

    截图: https://www.dropbox.com/s/betvc4palha8jp1/OcGuiscreen.jpg?dl=0

    我删除了slotUpdateUI()所有自定义小部件,并将代码清理到最低限度。剩下的就是静态UI,以及update()的定期调用。对焦CPU负载约为。 50%。一旦窗口失焦,百分比就会以每秒2%的速度上升。 另一个好奇心是初始聚焦百分比与UI大小线性相关(简单地删除空的右半部分将导致初始CPU负载减少20%。)

    我正在使用CMake构建。

    main.cpp中:

    #include "mainwindow.h"
    #include <QApplication>
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        MainWindow w;
        w.show();
    
        return a.exec();
    }
    

    mainwindow.h:

    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    
    #include <QMainWindow>
    #include <QtGui>
    #include <QtCore>
    
    namespace Ui {
    class MainWindow;
    }
    
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    
    public:
        explicit MainWindow(QWidget *parent = 0);
        ~MainWindow();
    
    private:
        Ui::MainWindow *ui;
    
    protected:
        void paintEvent(QPaintEvent* e);
        void keyPressEvent(QKeyEvent *e);
    
    
    
    signals:
    
    public slots:
    
    private slots:
    
    };
    
    #endif // MAINWINDOW_H
    

    mainwindow.cpp:

    #include <iostream>
    
    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    
    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
    
        QTimer* timer = new QTimer( this );
        connect( timer, SIGNAL( timeout() ), this, SLOT( update() ) );
        timer->start( 100 );
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    
    
    
    void MainWindow::paintEvent(QPaintEvent* e)
    {
    //    QPainter painter(this);
    }
    
    
    
    void MainWindow::keyPressEvent(QKeyEvent *e)
    {
        if(e->key() == Qt::Key_Escape || e->key() == Qt::Key_Q)
        {
            this->close();
        }
    }
    

0 个答案:

没有答案