在 Qt C++ 中的自定义项委托上绘制文本时的性能问题

Posted

技术标签:

【中文标题】在 Qt C++ 中的自定义项委托上绘制文本时的性能问题【英文标题】:Performance issues when painting text on custom item delegates in Qt C++ 【发布时间】:2017-08-03 13:22:23 【问题描述】:

目标:创建一个包含自定义文本内容的项目委托,用于QListView。

问题:在QAbstractItemDelegate 的子类的paint() 方法的重新实现中使用QPainter 绘制文本明显比绘制形状和像素图慢。将基类更改为QStyledItemDelegate 并不会提高速度。

设置: Qt 5.9.1,MSVC 2017,在 Windows 7/10 上测试

预研究:报告了类似的错误here,但在这种特殊情况下,即使不使用QPainter::setFont(),也会存在性能问题。 项目委托的 Qt 示例没有多大帮助,因为它们展示了如何绘制控件,而不仅仅是文本。

示例:下面给出的示例说明了这个问题。显示应用程序的窗口后,QListView 的内容显示有轻微但明显的延迟。在某些情况下,这种延迟最多会持续 几秒钟。当 view->setItemDelegate(new Delegate(this));painter->drawText(0, option.rect.y() + 18, index.data().toString()); 被评论时,在显示窗口和 QListView 的内容之间没有明显的延迟。

MainWindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QListView>
#include <QStandardItemModel>
#include "Delegate.h"

class MainWindow : public QMainWindow

    Q_OBJECT
public:
    explicit MainWindow(QWidget *parent = 0);
;

#endif // MAINWINDOW_H

MainWindow.cpp

#include "MainWindow.h"

MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)

    QStandardItemModel *model = new QStandardItemModel(this);
    QListView *view = new QListView(this);

    view->setModel(model);
    view->setItemDelegate(new Delegate(this));

    for (int n = 0; n < 100; n++)  model->appendRow(new QStandardItem("Test " +  QString::number(n))); 

    setCentralWidget(view);

Delegate.h

#ifndef DELEGATE_H
#define DELEGATE_H

#include <QAbstractItemDelegate>
#include <QPainter>

class Delegate : public QAbstractItemDelegate

    Q_OBJECT
public:
    explicit Delegate(QObject *parent = nullptr);

    void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
    QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const;
;

#endif // DELEGATE_H

Delegate.cpp

#include "Delegate.h"

Delegate::Delegate(QObject *parent) : QAbstractItemDelegate(parent)




void Delegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const

    painter->drawText(0, option.rect.y() + 18, index.data().toString());
    painter->drawLine(0, option.rect.y() + 19, option.rect.width(), option.rect.y() + 19);


QSize Delegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const

    return QSize(0, 20);

【问题讨论】:

单独index.data().toString()的表现如何? @Benjamin T,闪电般的快:) 挂在哪一行代码上? @JeffUK, painter-&gt;drawText(0, option.rect.y() + 18, index.data().toString()); 【参考方案1】:

现在我创建了一个bug report。我会用我收到的任何进一步信息更新这篇文章。

【讨论】:

以上是关于在 Qt C++ 中的自定义项委托上绘制文本时的性能问题的主要内容,如果未能解决你的问题,请参考以下文章

使用 QStyledItemDelegates 作为 QListView 中的自定义项

Qt QML 锚在自定义项中不起作用

Qt4:QAbstractTableModel 拖放 w/o MIME

如何使用菜单布局将自定义项添加到 NavigationView?

用于自定义项目的 C DLL

带有自定义项目的 QListView => 鼠标事件被传播