https://doc.qt.io/qt-5/qtwidgets-itemviews-stardelegate-example.html
一、介绍
star委托示例展示了如何创建一个可以自己绘制并支持编辑的委托。
当在QListView、QTableView或QTreeView中显示数据时,单个项由委托绘制。此外,当用户开始编辑项(例如,双击项)时,委托提供一个编辑器小部件,在进行编辑时,该小部件被放置在项的顶部。
委托是QAbstractItemDelegate的子类。Qt提供了QStyledItemDelegate,它继承了QAbstractItemDelegate并处理最常见的数据类型(特别是int和QString)。如果我们需要支持自定义数据类型,或者想要自定义现有数据类型的呈现或编辑,我们可以子类化QAbstractItemDelegate或QStyledItemDelegate。如果你需要Qt的模型/视图体系结构(包括委托)的高级介绍,请参阅委托类以获得更多关于委托和模型/视图编程的信息。
在本例中,我们将看到如何实现自定义委托来呈现和编辑“星级评级”数据类型,它可以存储诸如“5颗星中的1颗”这样的值。
这个例子由以下类组成:
- StarRating:是自定义数据类型。它存储以星表示的评级,如“5星中的2星”或“6星中的5星”。
- starDelegate:继承了QStyledItemDelegate并提供了对StarRating的支持(除了QStyledItemDelegate已经处理的数据类型之外)。
- StarEditor继承了QWidget,StarDelegate使用它来让用户使用鼠标编辑星级评级。
为了显示StarDelegate的实际操作,我们将用一些数据填充一个QTableWidget,并在其上安装delegate。
二、StarDelegate类
2.1定义
以下是StarDelegate类的定义:
class StarDelegate : public QStyledItemDelegate {
Q_OBJECT
public:
// 使用父类的构造函数
using QStyledItemDelegate::QStyledItemDelegate;
void paint(QPainter* painter, const QStyleOptionViewItem& option,
const QModelIndex& index) const override;
QSize sizeHint(const QStyleOptionViewItem& option,
const QModelIndex& index) const override;
QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option,
const QModelIndex& index) const override;
void setEditorData(QWidget* editor, const QModelIndex& index) const override;
void setModelData(QWidget* editor, QAbstractItemModel* model,
const QModelIndex& index) const override;
private slots:
void commitAndCloseEditor();
};
所有公共函数都是从QStyledItemDelegate中重新实现的虚函数,以提供自定义呈现和编辑。
2.2 实现
paint() 函数从QStyledItemDelegate中重新实现,并在视图需要重绘一个项目时调用
void StarDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option,
const QModelIndex& index) const
{
if (index.data().canConvert<StarRating>()) {
StarRating starRating = qvariant_cast<StarRating>(index.data());
if (option.state & QStyle::State_Selected)
painter->fillRect(option.rect, option.palette.highlight());
starRating.paint(painter, option.rect, option.palette,
StarRating::EditMode::ReadOnly);
} else {
QStyledItemDelegate::paint(painter, option, index);
}
}
该函数对每个项调用一次,由模型中的QModelIndex对象表示。如果存储在项目中的数据是StarRating,我们将自己绘制它;否则,我们让QStyledItemDelegate为我们绘制它。这确保了StarDelegate可以处理最常见的数据类型。
如果该项目是StarRating,那么如果该项目被选中,我们将绘制背景,并使用StarRating::paint()绘制该项目,
稍后我们将回顾这一点。
由于Q_DECLARE_METATYPE()宏出现在starrate .h中,StartRatings可以存储在QVariant中。稍后详细介绍。
当用户开始编辑条目时,createEditor()函数被调用:
QWidget* StarDelegate::createEditor(QWidget* parent,
const QStyleOptionViewItem& option,
const QModelIndex& index) const
{
if (index.data().canConvert<StarRating>()) {
StarEditor* editor = new StarEditor(parent);
connect(editor, &StarEditor::editingFinished,
this, &StarDelegate::commitAndCloseEditor);
return editor;
}
return QStyledItemDelegate::createEditor(parent, option, index);
}
如果条目是StarRating,我们创建一个StarEditor,并将它的editingFinished()信号连接到commitAndCloseEditor()槽,这样我们就可以在编辑器关闭时更新模型。
下面是commitAndCloseEditor()的实现:
void StarDelegate::commitAndCloseEditor()
{
StarEditor* editor = qobject_cast<StarEditor*>(sender());
emit commitData(editor);
emit closeEditor(editor);
}
当用户完成编辑时,我们发出commitData()和closeEditor()(都在QAbstractItemDelegate中声明),告诉模型有编辑过的数据,并通知视图不再需要编辑器。
setEditorData()函数在创建编辑器时调用,用来自模型的数据初始化编辑器:
void StarDelegate::setEditorData(QWidget* editor,
const QModelIndex& index) const
{
if (index.data().canConvert<StarRating>()) {
StarRating starRating = qvariant_cast<StarRating>(index.data());
StarEditor* starEditor = qobject_cast<StarEditor*>(editor);
starEditor->setStarRating(starRating);
} else {
QStyledItemDelegate::setEditorData(editor, index);
}
}
我们只需在编辑器上调用setStarRating()。
当编辑完成时,调用setModelData()函数将数据从编辑器提交给模型:
void StarDelegate::setModelData(QWidget* editor, QAbstractItemModel* model,
const QModelIndex& index) const
{
if (index.data().canConvert<StarRating>()) {
StarEditor* starEditor = qobject_cast<StarEditor*>(editor);
model->setData(index, QVariant::fromValue(starEditor->starRating()));
} else {
QStyledItemDelegate::setModelData(editor, model, index);
}
}
sizeHint()函数的作用是:返回一个元素的首选大小:
QSize StarDelegate::sizeHint(const QStyleOptionViewItem& option,
const QModelIndex& index) const
{
if (index.data().canConvert<StarRating>()) {
StarRating starRating = qvariant_cast<StarRating>(index.data());
return starRating.sizeHint();
}
return QStyledItemDelegate::sizeHint(option, index);
}
三、StarEditor类
3.1 定义
在实现StarDelegate时使用了StarEditor类。下面是类的定义:
class StarEditor : public QWidget {
Q_OBJECT
public:
StarEditor(QWidget* parent = nullptr);
QSize sizeHint() const override;
void setStarRating(const StarRating& starRating)
{
myStarRating = starRating;
}
StarRating starRating() { return myStarRating; }
signals:
void editingFinished();
protected:
void paintEvent(QPaintEvent* event) override;
void mouseMoveEvent(QMouseEvent* event) override;
void mouseReleaseEvent(QMouseEvent* event) override;
private:
int starAtPosition(int x) const;
StarRating myStarRating;
};
这个类允许用户通过将鼠标移到编辑器上来编辑StarRating。当用户单击编辑器时,它会发出editingFinished()信号。
受保护的函数从QWidget重新实现,以处理鼠标和绘图事件。私有函数starAtPosition()是一个辅助函数,它返回鼠标指针下的*号。
3.2 实现
让我们从构造函数开始:
StarEditor::StarEditor(QWidget* parent)
: QWidget(parent)
{
setMouseTracking(true);
setAutoFillBackground(true);
}
我们在小部件上启用鼠标跟踪,这样即使用户没有按下任何鼠标按钮,我们也可以跟踪光标。我们还打开了QWidget的自动填充背景特性,以获得不透明的背景。(如果没有调用,视图的背景将通过编辑器发光。)
它的paintEvent()函数从QWidget重新实现:
void StarEditor::paintEvent(QPaintEvent*)
{
QPainter painter(this);
myStarRating.paint(&painter, rect(), palette(),
StarRating::EditMode::Editable);
}
我们简单地调用StarRating::paint()来绘制星星,就像我们在实现StarDelegate时所做的那样。
void StarEditor::mouseMoveEvent(QMouseEvent* event)
{
const int star = starAtPosition(event->x());
if (star != myStarRating.starCount() && star != -1) {
myStarRating.setStarCount(star);
update();
}
QWidget::mouseMoveEvent(event);
}
在鼠标事件处理程序中,我们对私有数据成员myStarRating调用setStarCount()来反映当前光标的位置,并调用QWidget::update()来强制重绘。
void StarEditor::mouseReleaseEvent(QMouseEvent* event)
{
emit editingFinished();
QWidget::mouseReleaseEvent(event);
}
当用户释放鼠标按钮时,我们只发出editingFinished()信号。
int StarEditor::starAtPosition(int x) const
{
const int star = (x / (myStarRating.sizeHint().width() / myStarRating.maxStarCount())) + 1;
if (star <= 0 || star > myStarRating.maxStarCount())
return -1;
return star;
}
starAtPosition()函数使用基本的线性代数来找出光标下的星星。
sizeHint():首选的大小刚好足够绘制最大数目的星星。
QSize StarEditor::sizeHint() const
{
return myStarRating.sizeHint();
}
四、StarRating类
4.1 定义
class StarRating {
public:
enum class EditMode { Editable,
ReadOnly };
explicit StarRating(int starCount = 1, int maxStarCount = 5);
void paint(QPainter* painter, const QRect& rect,
const QPalette& palette, EditMode mode) const;
QSize sizeHint() const;
int starCount() const { return myStarCount; }
int maxStarCount() const { return myMaxStarCount; }
void setStarCount(int starCount) { myStarCount = starCount; }
void setMaxStarCount(int maxStarCount) { myMaxStarCount = maxStarCount; }
private:
QPolygonF starPolygon;
QPolygonF diamondPolygon;
int myStarCount;
int myMaxStarCount;
};
Q_DECLARE_METATYPE(StarRating)
StarRating类用一些星星表示一个评级。除了保存数据之外,它还能够在QPaintDevice上绘制星星,在本例中,QPaintDevice是一个视图或编辑器。myStarCount成员变量存储当前评级,而myMaxStarCount存储可能的最高评级(通常为5)。
Q_DECLARE_METATYPE()宏使QVariant知道StarRating类型,使得在QVariant中存储StarRating值成为可能。
4.2 实现
构造函数初始化myStarCount和myMaxStarCount,并设置用于绘制星星和菱形的多边形:
StarRating::StarRating(int starCount, int maxStarCount)
: myStarCount(starCount)
, myMaxStarCount(maxStarCount)
{
starPolygon << QPointF(1.0, 0.5);
for (int i = 1; i < 5; ++i)
starPolygon << QPointF(0.5 + 0.5 * std::cos(0.8 * i * 3.14),
0.5 + 0.5 * std::sin(0.8 * i * 3.14));
diamondPolygon << QPointF(0.4, 0.5) << QPointF(0.5, 0.4)
<< QPointF(0.6, 0.5) << QPointF(0.5, 0.6)
<< QPointF(0.4, 0.5);
}
paint()函数用于绘制绘制设备上StarRating对象中的星星:
void StarRating::paint(QPainter* painter, const QRect& rect,
const QPalette& palette, EditMode mode) const
{
painter->save();
painter->setRenderHint(QPainter::Antialiasing, true);
painter->setPen(Qt::NoPen);
painter->setBrush(mode == EditMode::Editable ? palette.highlight() : palette.windowText());
const int yOffset = (rect.height() - PaintingScaleFactor) / 2;
painter->translate(rect.x(), rect.y() + yOffset);
painter->scale(PaintingScaleFactor, PaintingScaleFactor);
for (int i = 0; i < myMaxStarCount; ++i) {
if (i < myStarCount) {
painter->drawPolygon(starPolygon, Qt::WindingFill);
} else if (mode == EditMode::Editable) {
painter->drawPolygon(diamondPolygon, Qt::WindingFill);
}
painter->translate(1.0, 0.0);
}
painter->restore();
}
五、main函数
下面是程序的main()函数:
int main(int argc, char* argv[])
{
QApplication app(argc, argv);
QTableWidget tableWidget(4, 4);
tableWidget.setItemDelegate(new StarDelegate);
tableWidget.setEditTriggers(QAbstractItemView::DoubleClicked
| QAbstractItemView::SelectedClicked);
tableWidget.setSelectionBehavior(QAbstractItemView::SelectRows);
tableWidget.setHorizontalHeaderLabels({ "Title", "Genre", "Artist", "Rating" });
populateTableWidget(&tableWidget);
tableWidget.resizeColumnsToContents();
tableWidget.resize(500, 300);
tableWidget.show();
return app.exec();
}
main()函数创建一个QTableWidget并在其上设置一个StarDelegate。DoubleClicked和SelectedClicked被设置为编辑触发器,这样当星型评级项目被选中时,编辑器就会随着一次单击而打开。
populateTableWidget()函数用数据填充QTableWidget:
void populateTableWidget(QTableWidget* tableWidget)
{
static constexpr struct {
const char* title;
const char* genre;
const char* artist;
int rating;
} staticData[] = {
{ "Mass in B-Minor", "Baroque", "J.S. Bach", 5 },
//! [1]
{ "Three More Foxes", "Jazz", "Maynard Ferguson", 4 },
{ "Sex Bomb", "Pop", "Tom Jones", 3 },
{ "Barbie Girl", "Pop", "Aqua", 5 },
{ nullptr, nullptr, nullptr, 0 }
};
for (int row = 0; staticData[row].title != nullptr; ++row) {
QTableWidgetItem* item0 = new QTableWidgetItem(staticData[row].title);
QTableWidgetItem* item1 = new QTableWidgetItem(staticData[row].genre);
QTableWidgetItem* item2 = new QTableWidgetItem(staticData[row].artist);
QTableWidgetItem* item3 = new QTableWidgetItem;
// 调用QVariant::fromValue将StarRating转换为QVariant
item3->setData(0, QVariant::fromValue(StarRating(staticData[row].rating)));
tableWidget->setItem(row, 0, item0);
tableWidget->setItem(row, 1, item1);
tableWidget->setItem(row, 2, item2);
tableWidget->setItem(row, 3, item3);
}
}
注意:调用QVariant::fromValue将StarRating转换为QVariant。
六、示例代码
stardelegate.h
#ifndef STARDELEGATE_H
#define STARDELEGATE_H
#include <QStyledItemDelegate>
class StarDelegate : public QStyledItemDelegate {
Q_OBJECT
public:
using QStyledItemDelegate::QStyledItemDelegate;
void paint(QPainter* painter, const QStyleOptionViewItem& option,
const QModelIndex& index) const override;
QSize sizeHint(const QStyleOptionViewItem& option,
const QModelIndex& index) const override;
QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option,
const QModelIndex& index) const override;
void setEditorData(QWidget* editor, const QModelIndex& index) const override;
void setModelData(QWidget* editor, QAbstractItemModel* model,
const QModelIndex& index) const override;
private slots:
void commitAndCloseEditor();
};
#endif
stardelegate.cpp
#include "stardelegate.h"
#include "stareditor.h"
#include "starrating.h"
#include <QtWidgets>
// paint()函数从QStyledItemDelegate中重新实现,并在视图需要重绘一个项目时调用
void StarDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option,
const QModelIndex& index) const
{
// 如果项目中的数据是StarRating,将自己绘制它;
// 否则让QStyledItemDelegate去绘制它, 这样可以让StarDelegate处理常见的数据类型
if (index.data().canConvert<StarRating>()) {
StarRating starRating = qvariant_cast<StarRating>(index.data());
// 如果该项目被选中, 我们将绘制背景, 并使用StarRating::paint()绘制该项目
if (option.state & QStyle::State_Selected) {
painter->fillRect(option.rect, option.palette.highlight());
}
starRating.paint(painter, option.rect, option.palette,
StarRating::EditMode::ReadOnly);
} else {
QStyledItemDelegate::paint(painter, option, index);
}
}
// 当用户开始编辑条目时,createEditor()函数被调用
QWidget* StarDelegate::createEditor(QWidget* parent,
const QStyleOptionViewItem& option,
const QModelIndex& index) const
{
// 如果条目是StarRating,我们创建一个StarEditor,并绑定信号槽,以确保在编辑器关闭时更新模型
if (index.data().canConvert<StarRating>()) {
StarEditor* editor = new StarEditor(parent);
connect(editor, &StarEditor::editingFinished,
this, &StarDelegate::commitAndCloseEditor);
return editor;
}
return QStyledItemDelegate::createEditor(parent, option, index);
}
// 当用户完成编辑时,我们发出commitData()和closeEditor(),告诉模型有编辑过的数据,并通知视图不再需要编辑器
void StarDelegate::commitAndCloseEditor()
{
StarEditor* editor = qobject_cast<StarEditor*>(sender());
// 以下两个信号在QAbstractItemDelegate中声明
emit commitData(editor);
emit closeEditor(editor);
}
// setEditorData()函数在创建编辑器时调用,用来自模型的数据初始化编辑器:
void StarDelegate::setEditorData(QWidget* editor,
const QModelIndex& index) const
{
if (index.data().canConvert<StarRating>()) {
StarRating starRating = qvariant_cast<StarRating>(index.data());
StarEditor* starEditor = qobject_cast<StarEditor*>(editor);
starEditor->setStarRating(starRating);
} else {
QStyledItemDelegate::setEditorData(editor, index);
}
}
// 我们只需在编辑器上调用setStarRating()。
// 当编辑完成时,调用setModelData()函数将数据从编辑器提交给模型:
void StarDelegate::setModelData(QWidget* editor, QAbstractItemModel* model,
const QModelIndex& index) const
{
if (index.data().canConvert<StarRating>()) {
StarEditor* starEditor = qobject_cast<StarEditor*>(editor);
model->setData(index, QVariant::fromValue(starEditor->starRating()));
} else {
QStyledItemDelegate::setModelData(editor, model, index);
}
}
// sizeHint()函数: 返回一个元素的首选大小
QSize StarDelegate::sizeHint(const QStyleOptionViewItem& option,
const QModelIndex& index) const
{
if (index.data().canConvert<StarRating>()) {
StarRating starRating = qvariant_cast<StarRating>(index.data());
return starRating.sizeHint();
}
return QStyledItemDelegate::sizeHint(option, index);
}
stareditor.h
#ifndef STAREDITOR_H
#define STAREDITOR_H
#include <QWidget>
#include "starrating.h"
// 在实现StarDelegate时使用了StarEditor类
class StarEditor : public QWidget {
Q_OBJECT
public:
StarEditor(QWidget* parent = nullptr);
QSize sizeHint() const override;
void setStarRating(const StarRating& starRating)
{
myStarRating = starRating;
}
StarRating starRating() { return myStarRating; }
signals:
void editingFinished();
protected:
void paintEvent(QPaintEvent* event) override;
void mouseMoveEvent(QMouseEvent* event) override;
void mouseReleaseEvent(QMouseEvent* event) override;
private:
int starAtPosition(int x) const;
StarRating myStarRating;
};
#endif
stareditor.cpp
#include "stareditor.h"
#include "starrating.h"
#include <QtWidgets>
StarEditor::StarEditor(QWidget* parent)
: QWidget(parent)
{
// 启用鼠标跟踪
setMouseTracking(true);
// QWidget的自动填充背景特性
setAutoFillBackground(true);
}
// paint()用来绘制星星, 就像我们在实现StarDelegate时所做的那样
void StarEditor::paintEvent(QPaintEvent*)
{
QPainter painter(this);
myStarRating.paint(&painter, rect(), palette(),
StarRating::EditMode::Editable);
}
// 通过调用StarRating类的setStarCount()来反映当前光标的位置, 并调用QWidget::update()来强制重绘
void StarEditor::mouseMoveEvent(QMouseEvent* event)
{
const int star = starAtPosition(event->x());
if (star != myStarRating.starCount() && star != -1) {
myStarRating.setStarCount(star);
update();
}
QWidget::mouseMoveEvent(event);
}
// 当用户释放鼠标按钮时, 发出editingFinished()信号
void StarEditor::mouseReleaseEvent(QMouseEvent* event)
{
emit editingFinished();
QWidget::mouseReleaseEvent(event);
}
// starAtPosition()函数使用基本的线性代数来找出光标下的星星
int StarEditor::starAtPosition(int x) const
{
const int star = (x / (myStarRating.sizeHint().width() / myStarRating.maxStarCount())) + 1;
if (star <= 0 || star > myStarRating.maxStarCount())
return -1;
return star;
}
// 首选的大小刚好足够绘制最大数目的星星
QSize StarEditor::sizeHint() const
{
return myStarRating.sizeHint();
}
starrating.h
#ifndef STARRATING_H
#define STARRATING_H
#include <QPainter>
#include <QPolygonF>
#include <QSize>
// StarRating类用一些星星表示一个评级, 保存数据与绘制星星
class StarRating {
public:
enum class EditMode { Editable,
ReadOnly };
explicit StarRating(int starCount = 1, int maxStarCount = 5);
void paint(QPainter* painter, const QRect& rect,
const QPalette& palette, EditMode mode) const;
QSize sizeHint() const;
int starCount() const { return myStarCount; }
int maxStarCount() const { return myMaxStarCount; }
void setStarCount(int starCount) { myStarCount = starCount; }
void setMaxStarCount(int maxStarCount) { myMaxStarCount = maxStarCount; }
private:
QPolygonF starPolygon;
QPolygonF diamondPolygon;
// 存储当前评级
int myStarCount;
// 存储可能的最高评级(通常为5)
int myMaxStarCount;
};
// Q_DECLARE_METATYPE()宏使QVariant知道StarRating类型,使得在QVariant中存储StarRating值成为可能。
Q_DECLARE_METATYPE(StarRating)
#endif
starrating.cpp
#include "starrating.h"
#include <QtWidgets>
#include <cmath>
constexpr int PaintingScaleFactor = 20;
// 构造函数初始化myStarCount和myMaxStarCount,并设置用于绘制星星和菱形的多边形:
StarRating::StarRating(int starCount, int maxStarCount)
: myStarCount(starCount)
, myMaxStarCount(maxStarCount)
{
starPolygon << QPointF(1.0, 0.5);
for (int i = 1; i < 5; ++i)
starPolygon << QPointF(0.5 + 0.5 * std::cos(0.8 * i * 3.14),
0.5 + 0.5 * std::sin(0.8 * i * 3.14));
diamondPolygon << QPointF(0.4, 0.5) << QPointF(0.5, 0.4)
<< QPointF(0.6, 0.5) << QPointF(0.5, 0.6)
<< QPointF(0.4, 0.5);
}
// 首选的大小刚好足够绘制最大数目的星星
QSize StarRating::sizeHint() const
{
return PaintingScaleFactor * QSize(myMaxStarCount, 1);
}
// paint()函数用于绘制绘制设备上StarRating对象中的星星
void StarRating::paint(QPainter* painter, const QRect& rect,
const QPalette& palette, EditMode mode) const
{
painter->save();
painter->setRenderHint(QPainter::Antialiasing, true);
painter->setPen(Qt::NoPen);
painter->setBrush(mode == EditMode::Editable ? palette.highlight() : palette.windowText());
const int yOffset = (rect.height() - PaintingScaleFactor) / 2;
painter->translate(rect.x(), rect.y() + yOffset);
painter->scale(PaintingScaleFactor, PaintingScaleFactor);
for (int i = 0; i < myMaxStarCount; ++i) {
if (i < myStarCount) {
painter->drawPolygon(starPolygon, Qt::WindingFill);
} else if (mode == EditMode::Editable) {
painter->drawPolygon(diamondPolygon, Qt::WindingFill);
}
painter->translate(1.0, 0.0);
}
painter->restore();
}
main.cpp
// star委托示例展示了如何创建一个可以自己绘制并支持编辑的委托。
#include "stardelegate.h"
#include "stareditor.h"
#include "starrating.h"
#include <QApplication>
#include <QTableWidget>
// 用数据填充QTableWidget
void populateTableWidget(QTableWidget* tableWidget)
{
static constexpr struct {
const char* title;
const char* genre;
const char* artist;
int rating;
} staticData[] = {
{ "Mass in B-Minor", "Baroque", "J.S. Bach", 5 },
//! [1]
{ "Three More Foxes", "Jazz", "Maynard Ferguson", 4 },
{ "Sex Bomb", "Pop", "Tom Jones", 3 },
{ "Barbie Girl", "Pop", "Aqua", 5 },
{ nullptr, nullptr, nullptr, 0 }
};
for (int row = 0; staticData[row].title != nullptr; ++row) {
QTableWidgetItem* item0 = new QTableWidgetItem(staticData[row].title);
QTableWidgetItem* item1 = new QTableWidgetItem(staticData[row].genre);
QTableWidgetItem* item2 = new QTableWidgetItem(staticData[row].artist);
QTableWidgetItem* item3 = new QTableWidgetItem;
// 调用QVariant::fromValue将StarRating转换为QVariant
item3->setData(0, QVariant::fromValue(StarRating(staticData[row].rating)));
tableWidget->setItem(row, 0, item0);
tableWidget->setItem(row, 1, item1);
tableWidget->setItem(row, 2, item2);
tableWidget->setItem(row, 3, item3);
}
}
int main(int argc, char* argv[])
{
QApplication app(argc, argv);
QTableWidget tableWidget(4, 4);
tableWidget.setItemDelegate(new StarDelegate);
tableWidget.setEditTriggers(QAbstractItemView::DoubleClicked
| QAbstractItemView::SelectedClicked);
tableWidget.setSelectionBehavior(QAbstractItemView::SelectRows);
tableWidget.setHorizontalHeaderLabels({ "Title", "Genre", "Artist", "Rating" });
populateTableWidget(&tableWidget);
tableWidget.resizeColumnsToContents();
tableWidget.resize(500, 300);
tableWidget.show();
return app.exec();
}