一直专注于功能的开发,没注意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); }
-----------------------------------------------------------------------------
第二个问题:
-----------------------------------------------------------------------------
第三个问题: