在DelegateItem中使用UI界面设计

摸索出来的东西,不一定靠谱。记录下来免得忘记了。

尝试将Creator设计的UI界面通过ItemDelegate来显示。

1. 利用Creator创建一个Widget

首先,利用Creator创建一个QWidget的UI和类,名字为SlideItemDelegate
最简单的做法是修改SlideItemDelegate的基类,它本来是一个QWidget的派生类,我们将其改为QStyledItemDelegate的派生类。
然后,将原先的QWidget放到它的类成员中。并添加QStyledItemDelegate需要重载的函数。如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
namespace Ui {
class SlideItemDelegate;
}

class SlideItemDelegate : public QStyledItemDelegate
{
Q_OBJECT

public:
explicit SlideItemDelegate(QWidget *parent = nullptr);
~SlideItemDelegate();
void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const override;
QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const override;

protected:
void changeEvent(QEvent *e);

private:
QScopedPointer<QWidget> _delegateWidget;
QScopedPointer<Ui::SlideItemDelegate> _ui;

这里最关键的是,我们重新定义了一个QWidget的指针_delegateWidget,至于是否是实现为智能指针,则完全看自己的喜好。下面的_ui也是同样的道理。

其构造函数也需要同样修改:

1
2
3
4
5
6
7
SlideItemDelegate::SlideItemDelegate(QWidget *parent)
: QStyledItemDelegate(parent)
, _delegateWidget{new QWidget}
, _ui{new Ui::SlideItemDelegate}
{
_ui->setupUi(_delegateWidget.data());
}

我们可以和一个普通的生成的界面对比一下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
namespace Ui {
class CellFinderForm;
}

class CellFinderForm : public QWidget
{
Q_OBJECT
public:
explicit CellFinderForm(QWidget *parent = nullptr);
~CellFinderForm();
private:
Ui::CellFinderForm *ui;
};

CellFinderForm::CellFinderForm(QWidget *parent) :
QWidget(parent),
ui(new Ui::CellFinderForm)
{
ui->setupUi(this);
}

2. 实现painter()sizeHint()函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

void SlideItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
if(index.data(Qt::UserRole).canConvert<SlideItem>())
{
SlideItem item = qvariant_cast<SlideItem>(index.data(Qt::UserRole));

_ui->socketId->setText(QString::number(item._socketId));
_ui->caseNo->setText(item._caseNo);
painter->save();
painter->translate(option.rect.topLeft());
_delegateWidget->render(painter, QPoint(), QRegion(), QWidget::DrawChildren);
painter->restore();
}
else
{
QStyledItemDelegate::paint(painter, option, index);
}
}

QSize SlideItemDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
{
return _delegateWidget->minimumSize();
}

3. 最关键的一步,需要将UI的尺寸设置为固定大小, 并设置它的最小尺寸。

这一步最为重要,否则,它不会显示。

比如,我们设置QListView的属性项:

  • resizeMode: Adjust
  • viewMode: IconMode

这些都不重要了。

4. 使用它

使用它很简单

1
2
3
_model.setItems(slides);
ui->listView->setItemDelegate(new SlideItemDelegate(this));
ui->listView->setModel(&_model);

唯一的差别在于需要调用ListView的setitemDelegate()函数来设置其

4. 改造为接受输入的

上面的界面运行不接受输入, 是只读界面. 仅仅能呈现数据.
如果要让他能够变成可读写的,还需要做哪些修改,要等我熟悉了之后再慢慢摸索。