- 浏览: 3416907 次
- 性别:
- 来自: 苏州
文章分类
最新评论
-
sonichy:
Qt5改动很多,要改改了。
基于QItemDelegate的例子1 SpinBoxDelegate -
我的主页6:
楼主,2.2子查询的分页方式:SELECT * FROM ar ...
Mysql 分页语句Limit用法 -
liguoqi:
非常感谢楼主的用心指导,工具以及图片例子都提供了 赞!
两款免费DCIOM 图像浏览软件介绍和DICOM图像例子供下载 -
liguoqi:
问下这个图片怎么解压损坏呀
两款免费DCIOM 图像浏览软件介绍和DICOM图像例子供下载 -
liguoqi:
楼主讲解的非常详细,还附带工具和图片例子,非常感谢
两款免费DCIOM 图像浏览软件介绍和DICOM图像例子供下载
有一个问题:QAbstractTableModel中的data()函数到底执行几遍???
发现问题的过程
1、一个普通的继承 QAbstractTableModel 的类
class CurrencyModel : public QAbstractTableModel { public: CurrencyModel(QObject *parent = 0); void setCurrencyMap(const QMap<QString, double> &map); int rowCount(const QModelIndex &parent) const; int columnCount(const QModelIndex &parent) const; QVariant data(const QModelIndex &index, int role) const; QVariant headerData(int section, Qt::Orientation orientation, int role) const; private: QString currencyAt(int offset) const; QMap<QString, double> currencyMap; };
2、其中的重载的data()函数如下:
//返回一个项的任意角色的值,这个项被指定为QModelIndex QVariant MoReconQueue::data(const QModelIndex &index, int role) const { qDebug() <<"role:"<< role<< "index : " << index.row() << index.column(); //模型索引无效,返回空值 if (!index.isValid()) return QVariant(); //对其角色 if (role == Qt::TextAlignmentRole) { return int(Qt::AlignRight | Qt::AlignVCenter); } //显示角色 else if (role == Qt::DisplayRole) { return reconQueueAt(index.row(),index.column()); } //返回空值 return QVariant(); }
3、测试结果:
发现data()执行了3次遍历,每次遍历都执行每一行每一项的七个角色的赋值。
role: 6 index : 0 0
role: 7 index : 0 0
role: 9 index : 0 0
role: 10 index : 0 0
role: 1 index : 0 0
role: 0 index : 0 0
role: 8 index : 0 0
我就纳闷了,执行一次遍历就够了,为啥要执行三遍呢。
Qt项数据角色如下:
enum Qt::ItemDataRole
Each item in the model has a set of data elements associated with it, each with its own role. The roles are used by the view to indicate to the model which type of data it needs. Custom models should return data in these types.
The general purpose roles (and the associated types) are:
Qt::DisplayRole | 0 | The key data to be rendered in the form of text. (QString) |
Qt::DecorationRole | 1 | The data to be rendered as a decoration in the form of an icon. (QColor, QIcon or QPixmap) |
Qt::EditRole | 2 | The data in a form suitable for editing in an editor. (QString) |
Qt::ToolTipRole | 3 | The data displayed in the item's tooltip. (QString) |
Qt::StatusTipRole | 4 | The data displayed in the status bar. (QString) |
Qt::WhatsThisRole | 5 | The data displayed for the item in "What's This?" mode. (QString) |
Qt::SizeHintRole | 13 | The size hint for the item that will be supplied to views. (QSize) |
Roles describing appearance and meta data (with associated types):
Qt::FontRole | 6 | The font used for items rendered with the default delegate. (QFont) |
Qt::TextAlignmentRole | 7 | The alignment of the text for items rendered with the default delegate. (Qt::AlignmentFlag) |
Qt::BackgroundRole | 8 | The background brush used for items rendered with the default delegate. (QBrush) |
Qt::BackgroundColorRole | 8 | This role is obsolete. Use BackgroundRole instead. |
Qt::ForegroundRole | 9 | The foreground brush (text color, typically) used for items rendered with the default delegate. (QBrush) |
Qt::TextColorRole | 9 | This role is obsolete. Use ForegroundRole instead. |
Qt::CheckStateRole | 10 | This role is used to obtain the checked state of an item. (Qt::CheckState) |
Accessibility roles (with associated types):
Qt::AccessibleTextRole | 11 | The text to be used by accessibility extensions and plugins, such as screen readers. (QString) |
Qt::AccessibleDescriptionRole | 12 | A description of the item for accessibility purposes. (QString) |
User roles:
Qt::UserRole | 32 | The first role that can be used for application-specific purposes. |
问题分析
1、经调试跟踪,Qt中的qtableview.h里面进行调用我们自定义的Modle
其中paint函数负责调用data()函数,我也很闷为啥绿色代码会遍历3次呢???那个Rects到底是什么值呢。。。其中的原理,我暂时还没搞明白。如果有知道的朋友,可以留言告诉我。谢谢
/*!
Paints the table on receipt of the given paint event \a event.
*/
void QTableView::paintEvent(QPaintEvent *event)
{
Q_D(QTableView);
// setup temp variables for the painting
QStyleOptionViewItemV4 option = d->viewOptionsV4();
const QPoint offset = d->scrollDelayOffset;
const bool showGrid = d->showGrid;
const int gridSize = showGrid ? 1 : 0;
const int gridHint = style()->styleHint(QStyle::SH_Table_GridLineColor, &option, this);
const QColor gridColor = static_cast<QRgb>(gridHint);
const QPen gridPen = QPen(gridColor, 0, d->gridStyle);
const QHeaderView *verticalHeader = d->verticalHeader;
const QHeaderView *horizontalHeader = d->horizontalHeader;
const QStyle::State state = option.state;
const bool alternate = d->alternatingColors;
const bool rightToLeft = isRightToLeft();
QPainter painter(d->viewport);
// if there's nothing to do, clear the area and return
if (horizontalHeader->count() == 0 || verticalHeader->count() == 0 || !d->itemDelegate)
return;
uint x = horizontalHeader->length() - horizontalHeader->offset() - (rightToLeft ? 0 : 1);
uint y = verticalHeader->length() - verticalHeader->offset() - 1;
const QRegion region = event->region().translated(offset);
const QVector<QRect> rects = region.rects();
//firstVisualRow is the visual index of the first visible row. lastVisualRow is the visual index of the last visible Row.
//same goes for ...VisualColumn
int firstVisualRow = qMax(verticalHeader->visualIndexAt(0),0);
int lastVisualRow = verticalHeader->visualIndexAt(verticalHeader->viewport()->height());
if (lastVisualRow == -1)
lastVisualRow = d->model->rowCount(d->root) - 1;
int firstVisualColumn = horizontalHeader->visualIndexAt(0);
int lastVisualColumn = horizontalHeader->visualIndexAt(horizontalHeader->viewport()->width());
if (rightToLeft)
qSwap(firstVisualColumn, lastVisualColumn);
if (firstVisualColumn == -1)
firstVisualColumn = 0;
if (lastVisualColumn == -1)
lastVisualColumn = horizontalHeader->count() - 1;
QBitArray drawn((lastVisualRow - firstVisualRow + 1) * (lastVisualColumn - firstVisualColumn + 1));
if (d->hasSpans()) {
d->drawAndClipSpans(region, &painter, option, &drawn,
firstVisualRow, lastVisualRow, firstVisualColumn, lastVisualColumn);
}
for (int i = 0; i < rects.size(); ++i) {
QRect dirtyArea = rects.at(i);
dirtyArea.setBottom(qMin(dirtyArea.bottom(), int(y)));
if (rightToLeft) {
dirtyArea.setLeft(qMax(dirtyArea.left(), d->viewport->width() - int(x)));
} else {
dirtyArea.setRight(qMin(dirtyArea.right(), int(x)));
}
// get the horizontal start and end visual sections
int left = horizontalHeader->visualIndexAt(dirtyArea.left());
int right = horizontalHeader->visualIndexAt(dirtyArea.right());
if (rightToLeft)
qSwap(left, right);
if (left == -1) left = 0;
if (right == -1) right = horizontalHeader->count() - 1;
// get the vertical start and end visual sections and if alternate color
int bottom = verticalHeader->visualIndexAt(dirtyArea.bottom());
if (bottom == -1) bottom = verticalHeader->count() - 1;
int top = 0;
bool alternateBase = false;
if (alternate && verticalHeader->sectionsHidden()) {
uint verticalOffset = verticalHeader->offset();
int row = verticalHeader->logicalIndex(top);
for (int y = 0;
((uint)(y += verticalHeader->sectionSize(top)) <= verticalOffset) && (top < bottom);
++top) {
row = verticalHeader->logicalIndex(top);
if (alternate && !verticalHeader->isSectionHidden(row))
alternateBase = !alternateBase;
}
} else {
top = verticalHeader->visualIndexAt(dirtyArea.top());
alternateBase = (top & 1) && alternate;
}
if (top == -1 || top > bottom)
continue;
// Paint each row item
for (int visualRowIndex = top; visualRowIndex <= bottom; ++visualRowIndex) {
int row = verticalHeader->logicalIndex(visualRowIndex);
if (verticalHeader->isSectionHidden(row))
continue;
int rowY = rowViewportPosition(row);
rowY += offset.y();
int rowh = rowHeight(row) - gridSize;
// Paint each column item
for (int visualColumnIndex = left; visualColumnIndex <= right; ++visualColumnIndex) {
int currentBit = (visualRowIndex - firstVisualRow) * (lastVisualColumn - firstVisualColumn + 1)
+ visualColumnIndex - firstVisualColumn;
if (currentBit < 0 || currentBit >= drawn.size() || drawn.testBit(currentBit))
continue;
drawn.setBit(currentBit);
int col = horizontalHeader->logicalIndex(visualColumnIndex);
if (horizontalHeader->isSectionHidden(col))
continue;
int colp = columnViewportPosition(col);
colp += offset.x();
int colw = columnWidth(col) - gridSize;
const QModelIndex index = d->model->index(row, col, d->root);
if (index.isValid()) {
option.rect = QRect(colp + (showGrid && rightToLeft ? 1 : 0), rowY, colw, rowh);
if (alternate) {
if (alternateBase)
option.features |= QStyleOptionViewItemV2::Alternate;
else
option.features &= ~QStyleOptionViewItemV2::Alternate;
}
d->drawCell(&painter, option, index);
}
}
alternateBase = !alternateBase && alternate;
}
if (showGrid) {
// Find the bottom right (the last rows/columns might be hidden)
while (verticalHeader->isSectionHidden(verticalHeader->logicalIndex(bottom))) --bottom;
QPen old = painter.pen();
painter.setPen(gridPen);
// Paint each row
for (int visualIndex = top; visualIndex <= bottom; ++visualIndex) {
int row = verticalHeader->logicalIndex(visualIndex);
if (verticalHeader->isSectionHidden(row))
continue;
int rowY = rowViewportPosition(row);
rowY += offset.y();
int rowh = rowHeight(row) - gridSize;
painter.drawLine(dirtyArea.left(), rowY + rowh, dirtyArea.right(), rowY + rowh);
}
// Paint each column
for (int h = left; h <= right; ++h) {
int col = horizontalHeader->logicalIndex(h);
if (horizontalHeader->isSectionHidden(col))
continue;
int colp = columnViewportPosition(col);
colp += offset.x();
if (!rightToLeft)
colp += columnWidth(col) - gridSize;
painter.drawLine(colp, dirtyArea.top(), colp, dirtyArea.bottom());
}
//draw the top & left grid lines if the headers are not visible.
//We do update this line when subsequent scroll happen (see scrollContentsBy)
if (horizontalHeader->isHidden() && verticalScrollMode() == ScrollPerItem)
painter.drawLine(dirtyArea.left(), 0, dirtyArea.right(), 0);
if (verticalHeader->isHidden() && horizontalScrollMode() == ScrollPerItem)
painter.drawLine(0, dirtyArea.top(), 0, dirtyArea.bottom());
painter.setPen(old);
}
}
发表评论
-
Qt官网变更【2012】
2012-09-21 19:30 4125Qt最近被Digia完全收购,诺基亚这两年的不理不睬,没有魄力 ... -
【转】QT实现不规则窗体
2012-09-21 18:50 4898看到好文章,收藏一下: 看到网上有很多不规则窗体的实现 ... -
Qt应用程序如何使用DCMTK类库进行二次开发DICOM数据传输
2012-09-13 09:35 0参考文章: 1、Using DCMTK with ... -
【转】将QT开发的界面程序封装成DLL,在VC中成功调用
2012-09-11 10:33 20973最近手头的一个项目需要做一个QT界面,并且封装成DLL,然后 ... -
诺基亚挥别Qt,转手给Digia
2012-09-11 09:37 2767一家总部位于芬兰的IT业务供应商Digia今天宣布,已经签署了 ... -
Qt多线程间信号槽传递非QObject类型对象的参数
2012-09-07 15:29 21177一、以前就发现过这个问题: 在Qt项目中,有时候为了 ... -
QT样式表(QStyleSheet)
2012-08-17 10:37 17793QT样式表 (QStyleSheet) 作者:刘旭晖 ... -
FinalData磁盘文件恢复工具(绿色破解版)
2012-08-02 13:28 8460FinalData磁盘文件恢复工具(绿色破解版),使用起来很方 ... -
Eclipse Qt开发环境的建立【转】
2012-08-01 11:15 43071.下载Eclipse目前Eclipse+CDT已经可以 ... -
汽车辐射监测系统-Qt开发
2012-07-25 16:18 4621最近晚上抽空忙了两个月,才把一个小系统做完。虽然做的不是太完 ... -
Qt做发布版,解决声音和图片、中文字体乱码问题
2012-07-14 16:02 4799Qt做发布版,解决声音和图片、中文字体乱码问题 ... -
QTableView使用中的疑问,如何及时显示操作Model后的结果?
2012-06-01 14:52 0最终的解决方法:我正 ... -
【转】Qt QTableview使用
2012-06-01 09:49 9606QTableWidget是QT程序中常用的显示数 ... -
QTableView双击 单机事件信号
2012-06-01 09:47 22867双击QTableView的行,获取该行数据 代码 ... -
QMessageBox改变大小
2012-05-31 15:33 8352创建一个QMessageBox: QMessageBo ... -
更新QTableView中的进度条状态
2012-05-30 14:37 14725前段时间,我接触了,如何在一个QTableView中加入一个控 ... -
QThread 线程暂停 停止功能的实现
2012-05-29 11:56 12105为了实现Qt中线程的暂停运行,和停止运行的控制功能 需要在设 ... -
QT环境变量
2012-05-28 18:53 5529不知道为啥同事有台电脑,装完Qt-VS2008库,和VS Ad ... -
广告光
2012-05-24 18:33 0盈创广告联盟 http://www.yo114.cn/ ... -
Test
2012-05-24 18:22 2128Test<IMG SRC="cf08e32c2 ...
相关推荐
QML用C++ QAbstractTableModel作为数据模型,进行数据展示
使用QabstractTableModel模型实现的一个示例、重写sort方法进行自定义排序,文章链接:https://www.cnblogs.com/lifexy/p/14144776.html
自己开发的集成qabstracttablemodel的派生类,附使用方法
自定义TableMode模型,继承QAbstractTableModel,自定义数据模型。 可以很快得加载完1000万行大数据,并且占用的内存也不大,可加载1千万行大数. 使用QVector作为模型的底层数据结构存储数据,其内存占用与QList相当...
Python-MongoDB-示例Python,Qt,PySide2,MongoDB,PyMongo,QTableView,QAbstractTableModel的实时工作示例应用程序提供了此应用程序的完整视频教程请订阅我的YouTube频道来吸引我。这是什么应用程序? 这是一个...
使用 AbstractTableModel 构建Table 在表格中添加JButton按钮,之前在网上找了2天没有找到好用的程序,最终终于找到一个好用的例子。 不要使,我退你们分。。 sing the Swing JTable class can quickly become a ...
qt开发的一个qabstractmodel的子类,方便tableview的数据编辑
Qt中模型视图QAbstranctItemModel、QAbstranctListModel、QAbstractTableModel核心功能重写实现。
Qt5开发及实例,实例CH802,通过实现将...(1)ModelEx类继承自QAbstractTableModel类,头文件“modelex.h”中的具体代码 (2)源文件“modelex.cpp”中的具体代码 data()函数返回指定索引的数据,即将数值映射为文字。
库中包含的报表设计器允许创建快速且直观的打印表单模板,该模板可以XML格式保存并用于生成报表页面。 可以将形成的页面发送到预览,PDF文件或打印机。 作为数据源,开发人员可以使用SQL数据库或使用...
从QAbstractTableModel派生自己的MyTableModel类,完成数据显示与编辑功能的参考工程。
QTableView实现,QAbstractTableModel添加数据,QStyledItemDelegate实现自定义item, QchekBox和和可点击按钮
qt demo工程由tableview表格与lineedit搜索输入框组成,代码实现qtableview的模型model部分继承至QAbstractTableModel的重写与视图view部分的重写,结合QSortFilterProxyModel的搜索过滤的功能与排序功能,通过...
库中包含的报表设计器允许创建快速直观的打印表单模板,该模板可以XML格式保存并用于生成报表页面。 因此,可以将形成的页面发送到预览,PDF文件或打印机。 作为数据源,开发人员可以使用SQL数据库或使用...
pyqt提供的几个视图类都可以较好工作,包括QLisView,QTableView和QTreeView。但是对于一些难以用现有的方式来呈现数据,这时,可以创建我们自己的视图子类并将其用做模型数据的可视化来解决这一问题。本文通过...
from PyQt5.QtCore import (QAbstractListModel, QAbstractTableModel, QModelIndex, QSize, QTimer, QVariant, Qt,pyqtSignal) from PyQt5.QtWidgets import (QApplication, QDialog, QHBoxLayout, QListView
它旨在与ECRUD项目一起工作(http://sourceforge.net/projects/easy-crud/)首先,它仅生成DAO Desing Pattern的代码,但随后我还添加了为模型生成代码的功能继承QAbstractTablemodel并从EZCRUD生成CustomEditor的...