【问题标题】:QListView set Custom Editor via QStyledItemDelegate::createEditorQListView 通过 QStyledItemDelegate::createEditor 设置自定义编辑器
【发布时间】:2022-01-15 16:53:39
【问题描述】:

我想在每个 QListView 单元格中显示自定义小部件(3 个标签宽度不同的字体和 2 个工具按钮)。 小部件必须处理鼠标事件才能正确处理悬停事件和按钮点击。 (因此我不能只在QStyledItemDelegate::paint() 中绘制它)。

这是我希望列表视图中每一行的样子:

主要思想: QAbstractItemView::openPersistentEditor().


#include <QApplication>

#include <QWidget>
#include <QHBoxLayout>
#include <QLabel>
#include <QToolButton>
#include <QVBoxLayout>

#include <QDateTime>

#include <QListView>
#include <QStringListModel>
#include <QStyledItemDelegate>

class Form : public QWidget
{
    //Q_OBJECT

public:
    explicit Form(QWidget *parent = nullptr)
        :QWidget(parent)
    {
        verticalLayout = new QVBoxLayout(this);
        horizontalLayout = new QHBoxLayout();

        labelTitle = new QLabel(this);
        labelTitle->setFont(QFont("Calibri", 12, QFont::Bold));
        horizontalLayout->addWidget(labelTitle);

        toolButtonEdit = new QToolButton(this);
        toolButtonEdit->setText("E");
        horizontalLayout->addWidget(toolButtonEdit);

        toolButtonRemove = new QToolButton(this);
        toolButtonRemove->setText("R");
        horizontalLayout->addWidget(toolButtonRemove);

        verticalLayout->addLayout(horizontalLayout);

        labelDate = new QLabel(this);
        labelDate->setFont(QFont("Calibri", 8));
        verticalLayout->addWidget(labelDate);

        labelText = new QLabel(this);
        labelText->setFont(QFont("Calibri", 10));
        verticalLayout->addWidget(labelText);

        verticalLayout->setStretch(2, 1);

        setMinimumSize(QSize(300, 50));
    }

public:
    QVBoxLayout *verticalLayout;
    QHBoxLayout *horizontalLayout;
    QLabel *labelTitle;
    QToolButton *toolButtonEdit;
    QToolButton *toolButtonRemove;
    QLabel *labelDate;
    QLabel *labelText;
};


class MyDelegate : public QStyledItemDelegate
{
public:
    QWidget* createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override
    {
        auto editor = new Form(parent);
        return editor;
    }

    void setEditorData(QWidget *ed, const QModelIndex &index) const override
    {
        QVariant var = index.model()->data(index, Qt::DisplayRole);

        if (Form *editor = dynamic_cast<Form*>(ed))
        {
            editor->labelTitle->setText("SYMBOL");
            editor->labelDate->setText("date-time");
            editor->labelText->setText(var.toString());
        }
    }
    void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem& option, const QModelIndex &)const override
    {
        editor->setGeometry(option.rect);
    }
};

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    Form form(nullptr);
    form.labelTitle->setText("TITLE");
    form.labelDate->setText(QDateTime::currentDateTime().toString());
    form.labelText->setText("text body");
    form.show();

    auto model = new QStringListModel;
    model->setStringList(QStringList()
        << "text body 1"
        << "text body 2"
        << "text body 3");

    auto view = new QListView(nullptr);
    view->setModel(model);
    view->setItemDelegate(new MyDelegate);

    int rowCount = model->rowCount();
    for (int row = 0; row < rowCount; ++row)
    {
        QModelIndex index = model->index(row, 0);
        view->openPersistentEditor(index);
    }

    view->show();

    return a.exec();
}

列表视图的实际外观如下:


如何设置这样一个自定义小部件来显示视图单元格?

【问题讨论】:

  • 你需要使用listView吗?相反,您能否使用 .ui 文件创建一个小部件,并为每个元素以编程方式实例化一个小部件并将其添加到垂直布局中?
  • @DaveK 不,我的数据在模型和代理模型中,我不能只避免模型/视图架构

标签: c++ qt qlistview qstyleditemdelegate


【解决方案1】:

请注意,当您定义自己的委托MyDelegate 时,您从未真正使用它(即通过调用QAbstractItemView::setItemDelegate()。因此,在调用openPersistentEditor() 时您会看到默认委托(QString 类型的数据的简单QLineEdit)。

【讨论】:

  • 谢谢,但如果我添加view-&gt;setItemDelegate(new MyDelegate);,代码会显示几个奇怪的分离窗口
  • 好吧,我们来看看“如何编写我自己的委托?”。分离的窗口通常表明小部件之间的父关系存在问题。查看您发布的代码,我们看到 Form 构造函数从未将 parent 参数传递给 QWidget 构造函数。这会导致您的 Form 根本没有父级,因为 QWidget 是默认使用 parent = nullptr 构造的,因此浮动在屏幕上的某个位置。
  • 已编辑此内容,谢谢。请问你能运行我的实际代码吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-01-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-04
  • 1970-01-01
相关资源
最近更新 更多