- 浏览: 3444018 次
- 性别:
- 来自: 苏州
文章分类
最新评论
-
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 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 23086双击QTableView的行,获取该行数据 代码 ... -
QMessageBox改变大小
2012-05-31 15:33 8439创建一个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 ...
相关推荐
在本文中,我们将深入探讨如何在Qt的QML环境中利用C++的`QAbstractTableModel`作为数据模型,以便在QML界面中展示数据。`QAbstractTableModel`是Qt的一个核心组件,它允许我们自定义数据模型,从而可以方便地与QML...
QT中的`QAbstractTableModel`是Qt库中一个非常重要的组件,它是`QAbstractItemModel`的一个子类,专为表格视图(如`QTableView`)设计,用于处理表格数据模型。在Qt的模型/视图框架中,模型是数据的提供者,视图则...
2. **自定义数据访问**:通过重载`QAbstractTableModel`的方法,如`data()`, `headerData()`, `insertRows()`, `removeRows()`等,可以控制如何获取、设置和管理数据。 3. **扩展功能**:可能需要添加额外的功能,...
自定义TableMode模型,继承QAbstractTableModel,自定义数据模型 TestQTableView3.,使用QVector作为模型的底层数据结构存储数据,其内存占用与QList相当,尾部追加插入耗时与QList相当,但头部插入比QList耗时较多
自定义TableMode模型,继承QAbstractTableModel,自定义数据模型。 可以很快得加载完1000万行大数据,并且占用的内存也不大,可加载1千万行大数. 使用QVector作为模型的底层数据结构存储数据,其内存占用与QList相当...
// 重写QAbstractTableModel的方法,如rowCount, columnCount, data, headerData等 private: // 存储数据的相关成员变量 }; ``` ```cpp // tablemodel.cpp TableModel::TableModel(QObject *parent) : ...
在创建电子表格程序时,你需要实现QAbstractTableModel的几个关键方法,如data()、headerData()、rowCount()和columnCount()等。data()用于获取单元格的数据,headerData()用于设置或获取列头和行头的信息,rowCount...
Python-MongoDB-示例Python,Qt,PySide2,MongoDB,PyMongo,QTableView,QAbstractTableModel的实时工作示例应用程序提供了此应用程序的完整视频教程请订阅我的YouTube频道来吸引我。这是什么应用程序? 这是一个...
8. **数据模型(QAbstractTableModel)**:对于更复杂的需求,你可以使用QAbstractTableModel类作为基础,创建自己的数据模型,这将允许你更好地控制数据的存储和显示方式。 9. **用户交互**:QTableWidget支持多种...
在这个项目中,我们可能会创建一个继承自QAbstractTableModel的自定义模型类,以便存储和操作文本数据。 自定义模型意味着我们需要重写几个关键的虚函数,例如`rowCount()`, `columnCount()`, `data()`, 和 `header...
在模型类中,我们需要添加额外的列来存储Checkbox的状态,并实现相应的数据访问接口,如`data()`、`flags()`和`setData()`。 ```cpp class CustomTableModel : public QAbstractTableModel { Q_OBJECT public: /...
创建一个自定义的模型类,继承自QAbstractTableModel,然后在`data()`方法中实现数据的获取和处理。接着,创建一个自定义委托,继承自QStyledItemDelegate,覆盖`paint()`和`editorEvent()`方法以实现特定的视觉...
在本文中,我们将深入探讨如何使用QT框架中的关键组件,如`QTableView`、`QAbstractTableModel`和`QStyledItemDelegate`,以及如何在这些组件中集成`QCheckBox`和可点击按钮,来实现一个功能丰富的MVC(模型-视图-...
在本文中,我们将深入探讨如何使用QT框架连接到MySQL数据库,并实时处理来自串口的数据,将其存储到数据库中,同时实现在线显示。这是一项在物联网(IoT)项目或实时数据监控应用中常见的任务。 首先,让我们了解基础...
QAbstractTableModel的接口如data()、headerData()、rowCount()和columnCount()等方法,是实现数据模型的关键。 "mainwindow.cpp"和"mainwindow.h"则是主窗口类,通常包含对整个应用程序界面的管理,包括创建和设置...
`MyCustomTableModel`需要继承自`QAbstractTableModel`,并实现其必要的接口,如`rowCount()`, `columnCount()`, `data()`, `headerData()`等,以便填充数据和响应视图的请求。 接下来,我们关注如何将数据加载到...
在`CSqlTableModel::data`中,你需要根据列的索引返回相应的值,这可能包括数据库中的字段值、显示的文本,甚至是自定义格式化后的信息。例如,你可能会根据数据类型进行转换,将整数或日期格式化为可读的字符串。 ...
- 创建一个继承自QAbstractTableModel的自定义模型类,实现必要的方法如rowCount()、columnCount()、data()等,以满足数据的读取需求。 - 在模型类中维护一个当前页的数据列表,以及总行数和每页行数的信息。 - ...
在QT中,QTableView是用于显示二维表格数据的主要控件,通常与QAbstractTableModel或QStandardItemModel一起使用。 要实现拖拽排序,我们需要对QTableView进行自定义。首先,我们需要重载QTableView的...
首先,我们需要了解Qt中的三种基本模型:QStandardItemModel、QAbstractListModel和QAbstractTableModel。QStandardItemModel是最简单的模型,适用于小型和简单的数据集;QAbstractListModel和QAbstractTableModel是...