qt - 在 QListView 的 QWidgetDelegate 的 paint() 方法中渲染 QWidget

标签 qt qwidget qpainter qlistview qstyleditemdelegate

我在 QListView 中实现自定义小部件渲染时遇到了困难.
我目前有一个 QListView显示我的自定义模型 PlayQueue基于 QAbstractListModel .

这适用于简单的文本,但现在我想为每个元素显示一个自定义小部件。
所以我将 QStyledItemDelegate 子类化实现paint像这样的方法:

void QueueableDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index ) const
{
    if (option.state & QStyle::State_Selected)
        painter->fillRect(option.rect, option.palette.highlight());
    QWidget *widget = new QPushButton("bonjour");
    widget->render(painter);
}

选择背景已正确呈现,但未显示任何小部件。我试过简单的QPainter像 Qt 示例中的命令,这工作正常:
void QueueableDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index ) const
{
    if (option.state & QStyle::State_Selected)
        painter->fillRect(option.rect, option.palette.highlight());
    if (option.state & QStyle::State_Selected)
        painter->setPen(option.palette.highlightedText().color());
    painter->setFont(QFont("Arial", 10));
    painter->drawText(option.rect, Qt::AlignCenter, "Custom drawing");
}

所以我尝试了一些更改,例如:
  • 更改 QStyledItemDelegateQItemDelegate
  • 添加 painter->save()painter->restore()围绕渲染
  • 将小部件几何设置为可用大小

  • 但是我现在有点卡住了,我在互联网上搜索了一段时间,但找不到任何我想要的示例,他们都在谈论编辑小部件(这更容易)或自定义绘制控件(预定义的,如进度条)。
    但在这里我真的需要一个我创建的自定义小部件,其中包含一些布局、标签和像素图。
    谢谢你的帮助!

    我在 Ubuntu 11.04 上为 GCC 使用 Qt 4.7.3。

    最佳答案

    只是为了完成整个画面:进一步可以找到使用委托(delegate)将 QWidget 管理为 QListView 项的代码。

    我终于找到了如何使用它的 paint(...) 方法使其在 QStyledItemDelegate 的子类中工作。

    它似乎比以前的解决方案更有效地提高性能,但是这个声明需要通过调查 setIndexWidget() 对创建的 QWidget 的作用来验证 =)。

    所以最后,这里是代码:

    class PackageListItemWidget: public QWidget
    

    ......
    class PackageListItemDelegate: public QStyledItemDelegate
    

    ......
    void PackageListItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index ) const
    {
    
    // here we have active painter provided by caller
    
    // by the way - we can't use painter->save() and painter->restore()
    // methods cause we have to call painter->end() method before painting
    // the QWidget, and painter->end() method deletes
    // the saved parameters of painter
    
    // we have to save paint device of the provided painter to restore the painter
    // after drawing QWidget
    QPaintDevice* original_pdev_ptr = painter->device();
    
    // example of simple drawing (selection) before widget
    if (option.state & QStyle::State_Selected)
        painter->fillRect(option.rect, option.palette.highlight());
    
    // creating local QWidget (that's why i think it should be fasted, cause we 
    // don't touch the heap and don't deal with a QWidget except painting)
    PackageListItemWidget item_widget;
    
    // Setting some parameters for widget for example
        // spec. params
    item_widget.SetPackageName(index.data(Qt::DisplayRole).toString());     
        // geometry
    item_widget.setGeometry(option.rect);
    
    // here we have to finish the painting of provided painter, cause
    //     1) QWidget::render(QPainter *,...) doesn't work with provided external painter 
    //          and we have to use QWidget::render(QPaintDevice *,...)
    //          which creates its own painter
    //     2) two painters can't work with the same QPaintDevice at the same time
    painter->end(); 
    
    // rendering of QWidget itself
    item_widget.render(painter->device(), QPoint(option.rect.x(), option.rect.y()), QRegion(0, 0, option.rect.width(), option.rect.height()), QWidget::RenderFlag::DrawChildren);   
    
    // starting (in fact just continuing) painting with external painter, provided
    // by caller
    painter->begin(original_pdev_ptr);  
    
    // example of simple painting after widget
    painter->drawEllipse(0,0, 10,10);   
    };
    

    关于qt - 在 QListView 的 QWidgetDelegate 的 paint() 方法中渲染 QWidget,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6452838/

    相关文章:

    python - 刷新 QWidget

    java - 我如何在 C++ 的堆栈上正确添加 QTWidgets?

    c++ - 在 QPainter::end() 之前调用 QImage::save() 是否安全

    c++ - 出错时停止代码执行 (C++)

    qt - 在 QT Creator 中使用自定义构造函数提升自定义小部件

    c++ - QPainter 保存状态

    python - 如何使用QPropertyAnimation配合QPainter绘制圆弧

    c++ - QWidget溢出

    c++ - QSortFilterProxyModel - 找出源模型的 id 索引在代理模型中

    c++ - 使用 CONFIG += staticlib 构建 Qt 应用程序会导致 "undefined reference to vtable"错误