在 Qt C++ 中的自定义项委托上绘制文本时的性能问题
Performance issues when painting text on custom item delegates in Qt C++
目标: 创建一个带有要在 QListView.
中使用的自定义文本内容的项目委托
问题:使用QPainter in a reimplementation of the paint()
method of a QAbstractItemDelegate's subclass is noticably slower than drawing shapes and pixmaps. Changing the base class to QStyledItemDelegate绘制文本并没有提高速度。
设置: Qt 5.9.1,MSVC 2017,在 Windows 7/10
上测试
预研: 报告了类似的错误 here,但是在这种特殊情况下,即使不使用 QPainter::setFont()
也存在性能问题。
项目委托的 Qt 示例没有多大帮助,因为它们展示了如何绘制控件,而不仅仅是文本。
示例: 下面给出的示例说明了这个问题。在显示应用程序的 window 之后,QListView 的内容显示有轻微但明显的延迟。在某些情况下,这种延迟最多会持续 几秒 。当评论 view->setItemDelegate(new Delegate(this));
或 painter->drawText(0, option.rect.y() + 18, index.data().toString());
时,显示 window 和 QListView.[=21= 的内容之间没有明显的延迟]
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);
}
现在我已经创建了一个 bug report。我将使用收到的任何进一步信息更新此 post。
目标: 创建一个带有要在 QListView.
中使用的自定义文本内容的项目委托问题:使用QPainter in a reimplementation of the paint()
method of a QAbstractItemDelegate's subclass is noticably slower than drawing shapes and pixmaps. Changing the base class to QStyledItemDelegate绘制文本并没有提高速度。
设置: Qt 5.9.1,MSVC 2017,在 Windows 7/10
上测试预研: 报告了类似的错误 here,但是在这种特殊情况下,即使不使用 QPainter::setFont()
也存在性能问题。
项目委托的 Qt 示例没有多大帮助,因为它们展示了如何绘制控件,而不仅仅是文本。
示例: 下面给出的示例说明了这个问题。在显示应用程序的 window 之后,QListView 的内容显示有轻微但明显的延迟。在某些情况下,这种延迟最多会持续 几秒 。当评论 view->setItemDelegate(new Delegate(this));
或 painter->drawText(0, option.rect.y() + 18, index.data().toString());
时,显示 window 和 QListView.[=21= 的内容之间没有明显的延迟]
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);
}
现在我已经创建了一个 bug report。我将使用收到的任何进一步信息更新此 post。