- 浏览: 3444050 次
- 性别:
- 来自: 苏州
文章分类
最新评论
-
sonichy:
Qt5改动很多,要改改了。
基于QItemDelegate的例子1 SpinBoxDelegate -
我的主页6:
楼主,2.2子查询的分页方式:SELECT * FROM ar ...
Mysql 分页语句Limit用法 -
liguoqi:
非常感谢楼主的用心指导,工具以及图片例子都提供了 赞!
两款免费DCIOM 图像浏览软件介绍和DICOM图像例子供下载 -
liguoqi:
问下这个图片怎么解压损坏呀
两款免费DCIOM 图像浏览软件介绍和DICOM图像例子供下载 -
liguoqi:
楼主讲解的非常详细,还附带工具和图片例子,非常感谢
两款免费DCIOM 图像浏览软件介绍和DICOM图像例子供下载
- 这节需要事件、绘图等基础知识,比较复杂。。。先收藏,后续学习。
Star Delegate Example
- itemviews/stardelegate/stardelegate.cpp
- itemviews/stardelegate/stardelegate.h
- itemviews/stardelegate/stareditor.cpp
- itemviews/stardelegate/stareditor.h
- itemviews/stardelegate/starrating.cpp
- itemviews/stardelegate/starrating.h
- itemviews/stardelegate/main.cpp
- itemviews/stardelegate/stardelegate.pro
- StarRating is the custom data type. It stores a rating expressed as stars, such as "2 out of 5 stars" or "5 out of 6 stars".
- StarDelegate inherits QItemDelegate and provides support for StarRating (in addition to the data types already handled byQItemDelegate).
- StarEditor inherits QWidget and is used by StarDelegate to let the user edit a star rating using the mouse.
- It is possible to open editors programmatically by calling QAbstractItemView::edit(), instead of relying on edit triggers. This could be use to support other edit triggers than those offered by the QAbstractItemView::EditTrigger enum. For example, in the Star Delegate example, hovering over an item with the mouse might make sense as a way to pop up an editor.
- By reimplementing QAbstractItemDelegate::editorEvent(), it is possible to implement the editor directly in the delegate, instead of creating a separate QWidget subclass.
The Star Delegate example shows how to create a delegate that can paint itself and that supports editing.
When displaying data in a QListView, QTableView, or QTreeView, the individual items are drawn by a delegate. Also, when the user starts editing an item (e.g., by double-clicking the item), the delegate provides an editor widget that is placed on top of the item while editing takes place.
Delegates are subclasses of QAbstractItemDelegate. Qt provides QItemDelegate, which inherits QAbstractItemDelegate and handles the most common data types (notably int and QString). If we need to support custom data types, or want to customize the rendering or the editing for existing data types, we can subclass QAbstractItemDelegate or QItemDelegate. See Delegate Classes for more information about delegates, and Model/View Programming if you need a high-level introduction to Qt's model/view architecture (including delegates).
In this example, we will see how to implement a custom delegate to render and edit a "star rating" data type, which can store values such as "1 out of 5 stars".
The example consists of the following classes:
To show the StarDelegate in action, we will fill a QTableWidget with some data and install the delegate on it.
StarDelegate Class Definition
Here's the definition of the StarDelegate class:
class StarDelegate : public QStyledItemDelegate { Q_OBJECT public: StarDelegate(QWidget *parent = 0) : QStyledItemDelegate(parent) {} void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const; QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const; void setEditorData(QWidget *editor, const QModelIndex &index) const; void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const; private slots: void commitAndCloseEditor(); };
All public functions are reimplemented virtual functions from QItemDelegate to provide custom rendering and editing.
StarDelegate Class Implementation
The paint() function is reimplemented from QItemDelegate and is called whenever the view needs to repaint an item:
void StarDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { if (qVariantCanConvert<StarRating>(index.data())) { StarRating starRating = qVariantValue<StarRating>(index.data()); if (option.state & QStyle::State_Selected) painter->fillRect(option.rect, option.palette.highlight()); starRating.paint(painter, option.rect, option.palette, StarRating::ReadOnly); } else { QStyledItemDelegate::paint(painter, option, index); }
The function is invoked once for each item, represented by a QModelIndex object from the model. If the data stored in the item is aStarRating, we paint it ourselves; otherwise, we let QItemDelegate paint it for us. This ensures that the StarDelegate can handle the most common data types.
In the case where the item is a StarRating, we draw the background if the item is selected, and we draw the item usingStarRating::paint(), which we will review later.
StartRatings can be stored in a QVariant thanks to the Q_DECLARE_METATYPE() macro appearing in starrating.h. More on this later.
The createEditor() function is called when the user starts editing an item:
QWidget *StarDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const { if (qVariantCanConvert<StarRating>(index.data())) { StarEditor *editor = new StarEditor(parent); connect(editor, SIGNAL(editingFinished()), this, SLOT(commitAndCloseEditor())); return editor; } else { return QStyledItemDelegate::createEditor(parent, option, index); } }
If the item is a StarRating, we create a StarEditor and connect its editingFinished() signal to our commitAndCloseEditor() slot, so we can update the model when the editor closes.
Here's the implementation of commitAndCloseEditor():
void StarDelegate::commitAndCloseEditor() { StarEditor *editor = qobject_cast<StarEditor *>(sender()); emit commitData(editor); emit closeEditor(editor); }
When the user is done editing, we emit commitData() and closeEditor() (both declared in QAbstractItemDelegate), to tell the model that there is edited data and to inform the view that the editor is no longer needed.
The setEditorData() function is called when an editor is created to initialize it with data from the model:
void StarDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const { if (qVariantCanConvert<StarRating>(index.data())) { StarRating starRating = qVariantValue<StarRating>(index.data()); StarEditor *starEditor = qobject_cast<StarEditor *>(editor); starEditor->setStarRating(starRating); } else { QStyledItemDelegate::setEditorData(editor, index); } }
We simply call setStarRating() on the editor.
The setModelData() function is called when editing is finished, to commit data from the editor to the model:
void StarDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const { if (qVariantCanConvert<StarRating>(index.data())) { StarEditor *starEditor = qobject_cast<StarEditor *>(editor); model->setData(index, qVariantFromValue(starEditor->starRating())); } else { QStyledItemDelegate::setModelData(editor, model, index); } }
The sizeHint() function returns an item's preferred size:
QSize StarDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const { if (qVariantCanConvert<StarRating>(index.data())) { StarRating starRating = qVariantValue<StarRating>(index.data()); return starRating.sizeHint(); } else { return QStyledItemDelegate::sizeHint(option, index); } }
We simply forward the call to StarRating.
StarEditor Class Definition
The StarEditor class was used when implementing StarDelegate. Here's the class definition:
class StarEditor : public QWidget { Q_OBJECT public: StarEditor(QWidget *parent = 0); QSize sizeHint() const; void setStarRating(const StarRating &starRating) { myStarRating = starRating; } StarRating starRating() { return myStarRating; } signals: void editingFinished(); protected: void paintEvent(QPaintEvent *event); void mouseMoveEvent(QMouseEvent *event); void mouseReleaseEvent(QMouseEvent *event); private: int starAtPosition(int x); StarRating myStarRating; };
The class lets the user edit a StarRating by moving the mouse over the editor. It emits the editingFinished() signal when the user clicks on the editor.
The protected functions are reimplemented from QWidget to handle mouse and paint events. The private function starAtPosition() is a helper function that returns the number of the star under the mouse pointer.
StarEditor Class Implementation
Let's start with the constructor:
StarEditor::StarEditor(QWidget *parent) : QWidget(parent) { setMouseTracking(true); setAutoFillBackground(true); }
We enable mouse tracking on the widget so we can follow the cursor even when the user doesn't hold down any mouse button. We also turn on QWidget's auto-fill background feature to obtain an opaque background. (Without the call, the view's background would shine through the editor.)
The paintEvent() function is reimplemented from QWidget:
void StarEditor::paintEvent(QPaintEvent *) { QPainter painter(this); myStarRating.paint(&painter, rect(), this->palette(), StarRating::Editable); }
We simply call StarRating::paint() to draw the stars, just like we did when implementing StarDelegate.
void StarEditor::mouseMoveEvent(QMouseEvent *event) { int star = starAtPosition(event->x()); if (star != myStarRating.starCount() && star != -1) { myStarRating.setStarCount(star); update(); } }
In the mouse event handler, we call setStarCount() on the private data member myStarRating to reflect the current cursor position, and we call QWidget::update() to force a repaint.
void StarEditor::mouseReleaseEvent(QMouseEvent * /* event */) { emit editingFinished(); }
When the user releases a mouse button, we simply emit the editingFinished() signal.
int StarEditor::starAtPosition(int x) { int star = (x / (myStarRating.sizeHint().width() / myStarRating.maxStarCount())) + 1; if (star <= 0 || star > myStarRating.maxStarCount()) return -1; return star; }
The starAtPosition() function uses basic linear algebra to find out which star is under the cursor.
StarRating Class Definition
class StarRating { public: enum EditMode { Editable, ReadOnly }; 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)
The StarRating class represents a rating as a number of stars. In addition to holding the data, it is also capable of painting the stars on aQPaintDevice, which in this example is either a view or an editor. The myStarCount member variable stores the current rating, andmyMaxStarCount stores the highest possible rating (typically 5).
The Q_DECLARE_METATYPE() macro makes the type StarRating known to QVariant, making it possible to store StarRating values inQVariant.
StarRating Class Implementation
The constructor initializes myStarCount and myMaxStarCount, and sets up the polygons used to draw stars and diamonds:
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 * cos(0.8 * i * 3.14), 0.5 + 0.5 * 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); }
The paint() function paints the stars in this StarRating object on a paint device:
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); if (mode == Editable) { painter->setBrush(palette.highlight()); } else { painter->setBrush(palette.foreground()); } 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 == Editable) { painter->drawPolygon(diamondPolygon, Qt::WindingFill); } painter->translate(1.0, 0.0); } painter->restore(); }
We first set the pen and brush we will use for painting. The mode parameter can be either Editable or ReadOnly. If mode is editable, we use the Highlight color instead of the Foreground color to draw the stars.
Then we draw the stars. If we are in Edit mode, we paint diamonds in place of stars if the rating is less than the highest rating.
The sizeHint() function returns the preferred size for an area to paint the stars on:
QSize StarRating::sizeHint() const { return PaintingScaleFactor * QSize(myMaxStarCount, 1); }
The preferred size is just enough to paint the maximum number of stars. The function is called by both StarDelegate::sizeHint() andStarEditor::sizeHint().
The main() Function
Here's the program's main() function:
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); QStringList headerLabels; headerLabels << "Title" << "Genre" << "Artist" << "Rating"; tableWidget.setHorizontalHeaderLabels(headerLabels); populateTableWidget(&tableWidget); tableWidget.resizeColumnsToContents(); tableWidget.resize(500, 300); tableWidget.show(); return app.exec(); }
The main() function creates a QTableWidget and sets a StarDelegate on it. DoubleClicked and SelectedClicked are set as edit triggers, so that the editor is opened with a single click when the star rating item is selected.
The populateTableWidget() function fills the QTableWidget with data:
void populateTableWidget(QTableWidget *tableWidget) { static const struct { const char *title; const char *genre; const char *artist; int rating; } staticData[] = { { "Mass in B-Minor", "Baroque", "J.S. Bach", 5 }, ... { 0, 0, 0, 0 } }; for (int row = 0; staticData[row].title != 0; ++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; item3->setData(0, qVariantFromValue(StarRating(staticData[row].rating))); tableWidget->setItem(row, 0, item0); tableWidget->setItem(row, 1, item1); tableWidget->setItem(row, 2, item2); tableWidget->setItem(row, 3, item3); } }
Notice the call to qVariantFromValue to convert a StarRating to a QVariant.
Possible Extensions and Suggestions
There are many ways to customize Qt's model/view framework. The approach used in this example is appropriate for most custom delegates and editors. Examples of possibilities not used by the star delegate and star editor are:
发表评论
-
Qt官网变更【2012】
2012-09-21 19:30 4213Qt最近被Digia完全收购,诺基亚这两年的不理不睬,没有魄力 ... -
【转】QT实现不规则窗体
2012-09-21 18:50 4988看到好文章,收藏一下: 看到网上有很多不规则窗体的实现 ... -
Qt应用程序如何使用DCMTK类库进行二次开发DICOM数据传输
2012-09-13 09:35 0参考文章: 1、Using DCMTK with ... -
【转】将QT开发的界面程序封装成DLL,在VC中成功调用
2012-09-11 10:33 21118最近手头的一个项目需要做一个QT界面,并且封装成DLL,然后 ... -
诺基亚挥别Qt,转手给Digia
2012-09-11 09:37 2858一家总部位于芬兰的IT业务供应商Digia今天宣布,已经签署了 ... -
Qt多线程间信号槽传递非QObject类型对象的参数
2012-09-07 15:29 21371一、以前就发现过这个问题: 在Qt项目中,有时候为了 ... -
QT样式表(QStyleSheet)
2012-08-17 10:37 17889QT样式表 (QStyleSheet) 作者:刘旭晖 ... -
FinalData磁盘文件恢复工具(绿色破解版)
2012-08-02 13:28 8582FinalData磁盘文件恢复工具(绿色破解版),使用起来很方 ... -
Eclipse Qt开发环境的建立【转】
2012-08-01 11:15 43741.下载Eclipse目前Eclipse+CDT已经可以 ... -
汽车辐射监测系统-Qt开发
2012-07-25 16:18 4693最近晚上抽空忙了两个月,才把一个小系统做完。虽然做的不是太完 ... -
Qt做发布版,解决声音和图片、中文字体乱码问题
2012-07-14 16:02 4863Qt做发布版,解决声音和图片、中文字体乱码问题 ... -
QTableView使用中的疑问,如何及时显示操作Model后的结果?
2012-06-01 14:52 0最终的解决方法:我正 ... -
【转】Qt QTableview使用
2012-06-01 09:49 9674QTableWidget是QT程序中常用的显示数 ... -
QTableView双击 单机事件信号
2012-06-01 09:47 23087双击QTableView的行,获取该行数据 代码 ... -
QMessageBox改变大小
2012-05-31 15:33 8440创建一个QMessageBox: QMessageBo ... -
更新QTableView中的进度条状态
2012-05-30 14:37 14855前段时间,我接触了,如何在一个QTableView中加入一个控 ... -
QThread 线程暂停 停止功能的实现
2012-05-29 11:56 12199为了实现Qt中线程的暂停运行,和停止运行的控制功能 需要在设 ... -
QT环境变量
2012-05-28 18:53 5593不知道为啥同事有台电脑,装完Qt-VS2008库,和VS Ad ... -
广告光
2012-05-24 18:33 0盈创广告联盟 http://www.yo114.cn/ ... -
Test
2012-05-24 18:22 2185Test<IMG SRC="cf08e32c2 ...
相关推荐
`DelegateExample` 提供了一个关于委托(Delegate)模式的简单示例。委托是一种设计模式,它允许类或对象将某些职责委派给其他对象,而不是直接执行这些职责。在Objective-C中,委托模式通过遵循特定的协议来实现。 ...
这是C#委托很经典很简单的一个例子,根据刘猛铁老师的C#语言入门详解系列视频中的案例的代码,适合初学者学习。这是C#委托很经典很简单的一个例子,根据刘猛铁老师的C#语言入门详解系列视频中的案例的代码,适合初学...
事件触发是事件驱动编程的核心,而委托(Delegate)则是实现事件处理的关键机制。本文将深入探讨事件触发与委托的概念,并通过一个简单的例子来演示它们的工作原理。 首先,让我们理解什么是事件。事件是一种封装了...
这个例子中的“qt model view Delegate”可能是为了演示如何有效地使用这些组件来实现复杂的用户界面功能。 在Qt中,模型(Model)存储和管理数据,可以是简单的列表或表格,也可以是复杂的数据结构。视图(View)...
标题中的"DelegateExample.rar"表明这是一个关于C#编程中委托(Delegate)的示例应用,而"C#编程_C#"进一步确认了我们正在讨论的是使用C#语言进行程序设计的主题。描述中的"simple application"提示我们将要探讨的是一...
在本项目"QT自定义混合控件——基于View/Model/Delegate的QTableView/QTreewidget/Combobox实现"中,我们将深入探讨如何利用QT库中的核心组件构建一个强大的数据展示和交互界面。 首先,我们要理解View/Model/...
在这个"C# Delegate小例子"中,我们将深入探讨Delegate的概念、使用方式以及它在实际编程中的应用。 1. **Delegate概念**: Delegate在C#中是一种类,它代表对方法的引用。这种引用是类型安全的,意味着在编译时就...
iOS 的delegate代码是http://blog.csdn.net/ilikeprograming/article/details/26206075的附件。这份代码有助于新手理解delegate。
在本项目中,我们关注的是基于View/Model/Delegate的QTableView、QTreewidget和QComboBox的实现。这三个组件是QT中用于数据展示和交互的重要控件。 首先,让我们详细了解View/Model/Delegate模式。这是QT中的一个...
下面,我们通过一个简单的例子来演示如何使用Delegate: 1. 首先,定义一个协议。假设我们有一个名为`MessageSender`的类,它需要向另一个对象发送消息。我们可以创建一个名为`MessageDelegate`的协议,其中包含一...
在名为`example`的压缩包中,可能包含了一个简单的示例,展示了如何创建一个Delegate来显示一个自定义的日期选择器控件。在这个例子中,我们可能看到`MyDateDelegate`类的定义,以及如何将其应用到QTableView的代码...
DelegateExample项目可能包含了一系列示例,演示了如何在实际应用中使用委托和UIStoryboardSegue。例如,一个简单的场景可能是:在一个登录界面,用户输入用户名和密码后点击“登录”按钮,触发一个...
在上面的例子中,`MyViewController`作为委托对象,实现了`MyDelegate`协议中的`didReceiveEvent`方法。当`DelegateOwner`触发`triggerEvent`时,它会通过`delegate`引用调用`didReceiveEvent`,将事件传递给`...
在这个例子中,ViewController类不仅继承自UIViewController,还遵循了SimpleDelegate协议,因此它必须实现`didTapButton:`方法。 3. **设置Delegate**: 在需要使用委托的对象中,通常会有一个属性来存储...
我自己写的一个博文配的例子,博文地址待审核后加上去。
C#例子代码 A0031_delegateC#例子代码 A0031_delegateC#例子代码 A0031_delegateC#例子代码 A0031_delegateC#例子代码 A0031_delegateC#例子代码 A0031_delegateC#例子代码 A0031_delegateC#例子代码 A0031_...
在iOS开发中,Delegate是一种非常重要的设计模式,用于对象间通信。它允许一个对象(委托者)通知另一个对象(委托对象)关于特定事件的发生。在iOS应用中,Delegate经常用于控制器间的通信,如UIViewController和...
在`Thread_delegateExample-master`这个项目中,可能包含了一个或者多个C#源文件,如`.cs`,展示了如何定义委托,创建线程,以及在不同线程之间使用委托来调用方法。 项目中的关键部分可能包括: 1. 委托的定义,如...
在Objective-C中,`delegate`是一种关键的编程模式,用于实现对象间的通信。本文将深入探讨如何在iPhone编程中使用`delegate`,并以一个名为"MyDelegateSample"的示例项目来说明。 首先,`delegate`是Objective-C中...
在iOS和macOS开发中,`delegate`、`NSNotification`和`block`是三种常见的对象间通信机制。它们各自有着不同的特性和应用场景,理解这些差异对于优化代码结构和提高程序性能至关重要。 首先,我们来看看`delegate`...