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

时间:2017-08-03 13:22:23

标签: c++ windows qt qt5 subclassing

目标:创建包含要在QListView中使用的自定义文字内容的项目委托。

问题:在重新实现QPainter子类的paint()方法时,使用QAbstractItemDelegate绘制文字明显慢于绘制形状和pixmaps。将基类更改为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);
}

1 个答案:

答案 0 :(得分:0)

现在我已经创建了bug report。我将根据收到的任何进一步信息更新这篇文章。