Qt QTableView paint() 事件无限期交付,消耗 1 个 CPU 内核的 100%

Posted

技术标签:

【中文标题】Qt QTableView paint() 事件无限期交付,消耗 1 个 CPU 内核的 100%【英文标题】:Qt QTableView paint() event delivered indefinitely which consumes 100% of 1 CPU core 【发布时间】:2019-02-02 22:02:30 【问题描述】:

在从 Qt 5.5.1 (Ubuntu 16.04) 升级到 Qt 5.9.5 (Ubuntu 18.04) 后,原本正常工作的代码(即使在 Ubuntu 14.04 附带的 Qt 上)开始消耗 100% 的 1 个 CPU 内核 - 绘制事件是无限期交付,无法接受:

void OutlinesTableView::paintEvent(QPaintEvent* event)

    verticalHeader()->setDefaultSectionSize(fontMetrics().height()*1.5);
    horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch);

    this->setColumnWidth(1, this->fontMetrics().averageCharWidth()*12);
    this->setColumnWidth(2, this->fontMetrics().averageCharWidth()*12);

    int normalizedWidth = width()/fontMetrics().averageCharWidth();
    if(normalizedWidth < SIMPLIFIED_VIEW_THRESHOLD_WIDTH) 
        this->setColumnWidth(3, 0);
     else 
        this->setColumnWidth(3, this->fontMetrics().averageCharWidth()*5);
    

    QTableView::paintEvent(event);
 

以上paintEvent() 再次获得相同的事件,并且无法停止。完整的代码清单可以在here找到。

【问题讨论】:

您在paintEvent 中输入的任何代码都不应该存在。该函数应该使用QPainter 进行自定义绘画,并且绝对没有布局调整等,因为其余更高级别的函数会触发更多绘画等。 @AlexanderV 您能否建议代码理想/典型的位置?是resize()还是其他方法?提前感谢您的任何指导! Martin:它可以是doc.qt.io/qt-5/qwidget.html#resizeEvent的事件处理程序 【参考方案1】:

本来我怀疑是拉伸模式——如果我把它去掉了,那么paint event loop就消失了,但根本原因是:

this->setColumnWidth(3, 0);

要隐藏列,最好使用:

this->setColumnHidden(3, true);

【讨论】:

您使原始代码的危害更小,但没有更正确。

以上是关于Qt QTableView paint() 事件无限期交付,消耗 1 个 CPU 内核的 100%的主要内容,如果未能解决你的问题,请参考以下文章

Linux QT 中控件QTableView相应鼠标事件

QT QTableview QItemDelegate 简单使用

paint 清除 qtableview 中的数据

Qt/QTableView/SQLite如何连接?

在 Qt 中为 QTableView 创建弹出菜单

Qt doubleClicked 事件发出两次