读Qt示例之Modbus Master example(一)
来源:互联网 发布:mac上安装apt get 编辑:程序博客网 时间:2024/06/08 05:53
读Qt示例之Modbus Master example(一)
本示例来自于Qt5.6.2
本篇主要看WriteRegisterModel这个模型类是怎么实现的
涉及知识点主要是model/view中的model
WriteRegisterModel有四个变量
public: int m_number; //读写的个数 int m_address; //读写的起始位置 QBitArray m_coils; //Coils QVector<quint16> m_holdingRegisters;//HoldlingRegister
Modbus 一共有四组变量,其中可写的是 Coils,HoldingRegisters
该示例每组变量一共有10个值,m_address是起始位置,m_number是从起始位置开始读几个。
实现只读功能
该模型是二维的,因此除了构造函数以外,只需要实现三个函数:rowCount(),columnCount()和data()函数。如果是字符串列表那样一维的,则只需实现rowCount()和data()函数。如果模型是树状图那样的层次结构,还需要实现index()和parent()函数.
其中rowCount(),columnCount()返回模型的行列数,data()返回指定模型索引的数据项。
也可以实现headerData()函数,它是显示表头的。
先看看构造函数
WriteRegisterModel::WriteRegisterModel(QObject *parent) : QAbstractTableModel(parent), m_coils(RowCount, false), m_holdingRegisters(RowCount, 0u){}
还有rowCount(),columnCount()
int WriteRegisterModel::rowCount(const QModelIndex &/*parent*/) const{ return RowCount;}int WriteRegisterModel::columnCount(const QModelIndex &/*parent*/) const{ return ColumnCount;}
这几个没啥好说的
data()函数:
QVariant WriteRegisterModel::data(const QModelIndex &index, int role) const{ if (!index.isValid() || index.row() >= RowCount || index.column() >= ColumnCount) return QVariant();//要求索引有效,行列号在大小范围之内 Q_ASSERT(m_coils.count() == RowCount); Q_ASSERT(m_holdingRegisters.count() == RowCount); if (index.column() == NumColumn && role == Qt::DisplayRole)//NumColumn被枚举为0 return QString::number(index.row());//第一列返回行号 if (index.column() == CoilsColumn && role == Qt::CheckStateRole) // coils return m_coils.at(index.row()) ? Qt::Checked : Qt::Unchecked;//返回是否被选中(at返回该位置的值) else if (index.column() == HoldingColumn && role == Qt::DisplayRole) //holding registers return QString("0x%1").arg(QString::number(m_holdingRegisters.at(index.row()), 16));//以十六进制返回指定位置的值 return QVariant();}
headerData()函数:
QVariant WriteRegisterModel::headerData(int section, Qt::Orientation orientation, int role) const{ if (role != Qt::DisplayRole) return QVariant(); if (orientation == Qt::Horizontal) { switch (section) { case NumColumn: return QStringLiteral("#"); case CoilsColumn: return QStringLiteral("Coils "); case HoldingColumn: return QStringLiteral("Holding Registers"); default: break; } } return QVariant();}
添加写功能
为了使模型可编辑,需要另外两个函数flags()和setData()
flags():
Qt::ItemFlags WriteRegisterModel::flags(const QModelIndex &index) const{ if (!index.isValid() || index.row() >= RowCount || index.column() >= ColumnCount) return QAbstractTableModel::flags(index); Qt::ItemFlags flags = QAbstractTableModel::flags(index); if ((index.row() < m_address) || (index.row() >= (m_address + m_number)))//如果index小于起始位置,大于结束位置,则返回0 flags &= ~Qt::ItemIsEnabled;//?不懂返回为什么这么写? if (index.column() == CoilsColumn) //coils return flags | Qt::ItemIsUserCheckable; if (index.column() == HoldingColumn) //holding registers return flags | Qt::ItemIsEditable; return flags;}
委托在创建编辑器以前会检测项目是否是可编辑的,模型必须让委托知道它的项目是可编辑的,这里为模型中的每一个项目返回一个正确的标识来达到这个目的。
setData():
bool WriteRegisterModel::setData(const QModelIndex &index, const QVariant &value, int role){ if (!index.isValid() || index.row() >= RowCount || index.column() >= ColumnCount) return false; Q_ASSERT(m_coils.count() == RowCount);//如果()里为0,返回警告 Q_ASSERT(m_holdingRegisters.count() == RowCount); if (index.column() == CoilsColumn && role == Qt::CheckStateRole) { // coils auto s = static_cast<Qt::CheckState>(value.toUInt());//?这里的类型转换为什么要这样? s == Qt::Checked ? m_coils.setBit(index.row()) : m_coils.clearBit(index.row()); emit dataChanged(index, index); return true; } if (index.column() == HoldingColumn && Qt::EditRole) { // holding registers bool result = false; quint16 newValue = value.toString().toUShort(&result, 16);//?还有这里? if (result) m_holdingRegisters[index.row()] = newValue; emit dataChanged(index, index); return result; } return false;}
注意,我们并不需要知道委托是怎样执行真正的编辑操作的,而只需要为委托向模型中设置一条途径,这个是通过setData()函数实现的(个人理解,这里不需要知道是怎样执行的是指:比如我没有找到setData函数被调用的地方,应该就是这种吧)
当数据被设置后,模型必须让视图知道有数据已经改变了,这就是最后都有个emit dataChanged(index, index);的意义
setData函数就是给这个item设置一个QVariant的值,但是,这个函数有两个参数,第一个QVariant自然是需要设置的值,另一个是一个int型数据,Qt中把这个称为role角色,所谓角色,是指设定进item的这个Qvariant所扮演的角色,实际就是对设定值的标定,因为item可以设置许多值,这就需要一个用以区分的标志,这个区分标志就叫角色。
- 读Qt示例之Modbus Master example(一)
- Qt示例[Mandelbrot Example]
- Qt之Modbus协议
- 读Qt示例之addressbook(一)
- Qt示例[Image Viewer Example]
- 【QT示例】XML Schema Validation Example
- Qt示例[2D Painting Example]
- Qt example之随机joke
- Qt example之随机笑话
- Qt example之 network joke
- Qt example 之 简易字典
- modbus TCP 示例报文
- qt-example之animated picture的学习
- JSON实战之savegame(Qt Example)
- Qt 之 Relational Table Model Example 解析
- Qt 之 Query Model Example 解析
- Qt 之 Cached Table Example 解析
- Modbus Master & Slave of WinCE on X86
- 新手上路之oracle 视图 索引(了解)笔记
- Redis单机版安装
- PHP系列—安装与配置(完全源码安装)
- 设计模式-代理模式
- 从bootm 命令讲起/U-boot的环境变量: bootcmd 和bootargs
- 读Qt示例之Modbus Master example(一)
- 移动页面的真机测试
- Hihocoder 1432 JiLi Number (数论)
- web中解决表单重复提交
- linux学习之旅(一)&& 开始
- 7.16深度学习框架
- EngineerCMS与ProjectWise对比
- 点分治
- FTP、TFTP、NFS的区别