• 开发的时候,一定要及时控制CPU使用率以及使用内存大小等三个问题(一个星期检查一次)


    一直专注于功能的开发,没注意CPU和内存。昨天无意中发现两个问题:

    1. 程序启动后,什么都没干,CPU就50%了(单核)。现在想找原因降低使用率,感觉无从下手,要是平时就注意这个问题就好了。

    2. 程序随着功能的运行,内存不断增长。内存泄漏的情况也有,但很少,都是几K几K的增长,这个还不要紧。但是更关键的是,在线程中运行数据的时候,建立了几个超大Map,偏偏写了一句deleteLater即在线程运行完毕之后自动释放内存,同时也会释放这几个超大Map,但是你不知道QT库会何时删除这个线程啊,导致程序内存从20M一下子变成几百M,而且不会降低。我学聪明了,在Map数据不需要以后,就clear,这样不影响后面的逻辑。目前不知道还有没有别的因素需要控制。要开发一个完整的软件还真是不容易。

    3. 内存占用大以后,程序反应很慢,可我的机子内存明明有16G之多,为什么还是慢呢?

    -----------------------------------------------------------------------------

    第一个问题:CPU占用率狂增,已经知道为什么了,因为按钮上的图片在不断的刷新显示,每秒都要读取8次图片资源并刷新。

    有错误的代码如下:

    void ToolButton::setMousePress(bool mouse_press)
    {
        this->mouse_press = mouse_press; // 记录状态
        if(mouse_press) button_select = true;
        else button_select = false;
        //qDebug() << "mouse_press=" << mouse_press;
        //qDebug() << "button_select=" << button_select;
        update(); // UI 按下了就要有反应,所以必须重绘(估计会调用paintEvent函数)
    }
    
    void ToolButton::paintEvent(QPaintEvent *event)
    {
        //qDebug() << "button_select=" << button_select;
        // UI qqq fixme 怎么在完全不动界面的情况下,也会永远不停的自绘?
        QPainter painter(this);
        if(mouse_over)
        {
            //qDebug() << "paintEvent 000 mouse_over";
            //绘制鼠标移到按钮上的按钮效果
            // UI 点击之后,瞬间就结束了。剩下的时间,都处于按钮的over状态,所以这时必须一直重绘
            if(mouse_press) {
                QPixmap pixmap;
                pixmap.load(pic_name1);
                setIcon(pixmap);
                if (button_number<=1) {
                    setStyleSheet("color: #3D4A54; background : #C1F1FA;");
                }
                else setStyleSheet("color: #F5997B;"); // 小按钮变成红色
            }
        }
        else
        {
            // qDebug() << "paintEvent else";
            // 一般情况下
            if(button_select)
            {
                // UI 当按钮被按下以后,这个按钮的mouse_press总是处于true的状态,所以会不停的重绘
                // fixme 所有的按钮都是这样吗?效率太低?
                // qDebug() << "paintEvent 111 mouse_press";
                QPixmap pixmap;
                pixmap.load(pic_name1);
                setIcon(pixmap);
                setStyleSheet("color: #F5997B;"); // 红色,小按钮按下之后的文字前景色            
                if (button_number<=1) setStyleSheet("color: #3D4A54; background : #C1F1FA;");
            } else {
                // 总是执行
                // qDebug() << "paintEvent 222 else";
                QPixmap pixmap;
                pixmap.load(pic_name);
                setIcon(pixmap);
                //setStyleSheet("color: #646E76;");
                setStyleSheet("color: #3D4A54;"); // 灰色,小按钮取消选中之后的文字前景色
                if (button_number<=1) setStyleSheet("color: #3D4A54; background : #F4F4F4;");
            }
        }
    
        QToolButton::paintEvent(event);
    }

    正确的代码如下:

    void ToolButton::setMousePress(bool mouse_press)
    {
        this->mouse_press = mouse_press; // 记录状态
        // qDebug() << "mouse_press=" << mouse_press;
        if(mouse_press) {
            QPixmap pixmap(pic_name1); // UI 红色图片,这里最关键
            setIcon(pixmap);
            setIconSize(pixmap.size());
            if (button_number<=1) {
                setStyleSheet("color: #3D4A54; background : #C1F1FA;");
            }
        }
        else {
            QPixmap pixmap(pic_name);
            setIcon(pixmap);
            setIconSize(pixmap.size());
            if (button_number<=1) {
                setStyleSheet("color: #3D4A54; background : #F4F4F4;");
            }
        }
    
        // update(); // UI 按下了就要有反应,所以必须重绘(估计会调用paintEvent函数)。但是如果是换图片,就不必重绘了
    }
    
    void ToolButton::paintEvent(QPaintEvent *event)
    {
        // Archi exp 曾经造成CPU满格,就是因为不断刷新。其实只要一次性刷新即可
        // 必须有条件才能执行函数内容,否则就会永久不间断刷新
        // 其实就是我没有理解这个函数,只有需要特殊效果的时候,才在这里画一下。
        // 之前8个按钮根据按钮的选择情况,永久不间断刷新。其实一次性设好图片即可,根本不必刷新
        // 而且是不断读入图片,并设置QSS,然后更新图像,比单纯使用GDI刷新复杂多了
        // 如果不是动态效果,而只是设置图片,根本不必在这里设置。只有某些动态GDI才需要这里设置
    
        QPainter painter(this);
        if(mouse_over)
        {
            // qDebug() << "paintEvent mouse_over"; // UI 鼠标进入按钮区域后,此处只执行一次
            // 可在这里绘制一些动态GDI效果,比如:
            // painterInfo(0, 100, 150);
        }
        else
        {
            // qDebug() << "paintEvent always";
        }
    
        QToolButton::paintEvent(event);
    }

    另外可参考的代码如下(一般不执行):

    void ToolButton::setMousePress(bool mouse_press)
    {
        this->mouse_press = mouse_press;
        update();
    }
    
    void ToolButton::paintEvent(QPaintEvent *event)
    {
        if(mouse_over)
        {
            //绘制鼠标移到按钮上的按钮效果
            painterInfo(0, 100, 150);
        }
        else
        {
            if(mouse_press)
            {
                painterInfo(0, 100, 150);
            }
        }
    
        QToolButton::paintEvent(event);
    }

    -----------------------------------------------------------------------------

    第二个问题:

    -----------------------------------------------------------------------------

    第三个问题:

  • 相关阅读:
    申请奖励加分
    6.14
    6.11
    6.10
    6.9
    6.8
    6.7
    6.6
    6.5
    6.4
  • 原文地址:https://www.cnblogs.com/findumars/p/4686675.html
Copyright © 2020-2023  润新知