摸索出来的东西,不一定靠谱。记录下来免得忘记了。
补充: 后来在手册中发现, 对于QTabWidget, QListWidget这类, 直接使用setWidget()方法就可以直接实现, 不需要这么复杂.
对于需要在List/Table等里面嵌入控件的场景来说, 使用View
类本身就是小题大作, 用Widget
类就够了.
在DelegateItem中使用UI界面设计
尝试将Creator设计的UI界面通过ItemDelegate来显示。
首先,利用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. 改造为接受输入的
上面的界面运行不接受输入, 是只读界面. 仅仅能呈现数据.
如果要让他能够变成可读写的,还需要做哪些修改,要等我熟悉了之后再慢慢摸索。