简述

在GUI开发中,往往需要在界面中存储一些有用的数据,这些数据可以来自配置文件、注册表、数据库、或者是Server。

无论来自哪里,这些数据对于用户来说都是至关重要的,它们在交互过程中大部分都会被用到,例如:单击一个用户头像,显示该用户的详细信息(等级、昵称、姓名、个人说明)。

常见接口

Qt中,可以通过绝大部分已有的接口来存数数据、获取数据。例如:

  • 存储数据

    • setData()
    • setItemData()
    • setUserData()
  • 获取数据:

    • data()
    • itemData()
    • userData()

常用的基本就这些,当然,还有其他的一些接口。。。

数据源

为了便于演示,我们定义两个数据源:结构体User、枚举LANGUAGE。

// 用户信息
struct User : QObjectUserData {
int nID; // ID
QString strName; // 用户名
}; // 语言
typedef enum{
UI_ZH, // 中文
UI_EN // 英文
} LANGUAGE; Q_DECLARE_METATYPE(User)
Q_DECLARE_METATYPE(LANGUAGE)

其中,User定义为QObjectUserData类型,为了后面setUserData()和userData()使用。如果不使用这两个接口,则不需要定义为QObjectUserData。

绝大部分存储用户数据的接口都使用的是QVariant,也就是我们常说的“万能变量”。对于自定义数据类型,如果要使用QVariant,就必须使用Q_DECLARE_METATYPE注册。

setData()和data()

创建一个QListWidget列表,添加5个Item项,然后给每一个都存储属于自己的数据。

单独存储

通过setData(),我们可以单独存储用户数据,使用Qt::UserRole、Qt::UserRole + 1……

QListWidget *pListWidget = new QListWidget(this);
int i = 0;
do {
++i;
QListWidgetItem *pItem = new QListWidgetItem(pListWidget);
pItem->setData(Qt::UserRole, i); // 用户数据
pItem->setData(Qt::UserRole + 1, QString("Qter %1").arg(i)); // 用户数据
pItem->setText(QString("Item %1").arg(i)); // 文本
pListWidget->addItem(pItem);
} while (i < 5); // 连接信号槽
connect(pListWidget, &QListWidget::itemClicked, this, &MainWindow::onItemClicked);

槽函数,获取用户数据,执行相应操作。

void onItemClicked(QListWidgetItem *item) {
int nID = item->data(Qt::UserRole).toInt(); // 获取用户数据
QString strName = item->data(Qt::UserRole + 1).toString(); // 获取用户数据 qDebug() << "ID : " << nID;
qDebug() << "Name : " << strName;
}

整体存储

也可以通过setData()进行整体存储,这时候只需要使用Qt::UserRole即可,把用户数据当成一个结构体来存储。

QListWidget *pListWidget = new QListWidget(this);
int i = 0;
do {
++i;
QListWidgetItem *pItem = new QListWidgetItem(pListWidget);
User user;
user.nID = i;
user.strName = QString("Qter %1").arg(i);
pItem->setData(Qt::UserRole, QVariant::fromValue(user)); // 设置用户数据
pItem->setText(QString("Item %1").arg(i));
pListWidget->addItem(pItem);
} while (i < 5);

槽函数,获取用户数据,执行相应操作。

void onItemClicked(QListWidgetItem *item)
{
QVariant variant = item->data(Qt::UserRole); // 获取用户数据
User user = variant.value<User>();
qDebug() << "ID : " << user.nID; qDebug() << "Name : " << user.strName;
}

  

无论那种方式都可以,如果在信号和槽的传递过程中,参数过多,建议使用“整体存储”方式。

setItemData()和itemData()

Qt之国际化一节中,分享了多语言的切换,下面就以此为例:

QComboBox *pComboBox = new QComboBox(this);
pComboBox->addItem("Chinese");
pComboBox->addItem("English");
pComboBox->setItemData(0, QVariant::fromValue(UI_ZH)); // 设置用户数据
pComboBox->setItemData(1, QVariant::fromValue(UI_EN)); // 设置用户数据 // 连接信号槽
connect(pComboBox, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &MainWindow::onCurrentIndexChanged);

槽函数,获取用户数据,执行相应操作。

void onCurrentIndexChanged(int index) {
// 获取发送者
QObject *pObject = this->sender();
QComboBox *pComboBox = qobject_cast<QComboBox *>(pObject); // 获取用户数据
QVariant variant = pComboBox->itemData(index);
LANGUAGE language = variant.value<LANGUAGE>(); qDebug() << "Language : " << language;
}

setUserData()和userData()

通过setUserData(),我们可以存储用户数据。

注意:用户数据需要被定义为QObjectUserData类型。

QPushButton *pButton = new QPushButton(this);
pButton->setText("Qter"); // 用户数据
User *pUser = new User();
pUser->nID = 1;
pUser->strName = "Qter"; pButton->setUserData(Qt::UserRole, pUser); // 设置用户数据 // 连接信号槽
connect(pButton, &QPushButton::clicked, this, &MainWindow::onClicked);

槽函数,获取用户数据,执行相应操作。

void onClicked() {
// 获取发送者
QObject *pObject = this->sender();
QPushButton *pButton = qobject_cast<QPushButton *>(pObject); // 获取用户数据
User *pUser = (User *)(pButton->userData(Qt::UserRole)); qDebug() << "ID : " << pUser->nID;
qDebug() << "Name : " << pUser->strName;
}

通过userData()可以获取QObjectUserData数据,然后转换成我们需要的类型User。

自定义数据

用现有的接口固然方便,有时对于复杂的功能,我们也不得不自定义。

举一个简单的例子:

#include <QPushButton>

class PushButton : public QPushButton
{
Q_OBJECT public:
explicit PushButton(QWidget *parent = 0)
: QPushButton (parent),
m_nID(-1),
m_strName("")
{
} void setID(int id) {
m_nID = id;
} void setName(QString name) {
m_strName = name;
} int id() const {
return m_nID;
} QString name() const {
return m_strName;
} private:
int m_nID;
QString m_strName; };

我们定义了一个按钮QPushButton,可以通过setID()、setName()来设置ID和名称信息,如果要获取信息,则可以调用id()、name()函数。

使用很简单:

PushButton *pButton = new PushButton(this);
pButton->setText("Qter"); // 设置自定义数据
pButton->setID(1);
pButton->setName("Qter"); // 连接信号槽
connect(pButton, &QPushButton::clicked, this, &MainWindow::onClicked);

槽函数,获取用户数据,执行相应操作。

void onClicked() {
// 获取发送者
QObject *pObject = this->sender();
PushButton *pButton = qobject_cast<PushButton *>(pObject); // 获取用户数据
qDebug() << "ID : " << pButton->id();
qDebug() << "Name : " << pButton->name();
}

基本的数据存储与获取方式就这些.

https://blog.csdn.net/swartz_lubel/article/details/55195509

qt setData()和data()的更多相关文章

  1. Qt之QTableView添加复选框(QAbstractTableModel)

    简述 使用QTableView,经常会遇到复选框,要实现一个好的复选框,除了常规的功能外,还应注意以下几点: 三态:不选/半选/全选 自定义风格(样式) 下面我们介绍一下常见的实现方式: 编辑委托. ...

  2. Qt之界面数据存储与获取(使用setUserData()和userData())

    在GUI开发中,往往需要在界面中存储一些有用的数据,这些数据可以来配置文件.注册表.数据库.或者是server. 无论来自哪里,这些数据对于用户来说都是至关重要的,它们在交互过程中大部分都会被用到,例 ...

  3. qt超强精美绘图控件 - QCustomPlot一览 及 安装使用教程

    1.概述 QCustomPlot 是一个超强超小巧的qt绘图类,非常漂亮,非常易用,只需要加入一个qcustomplot.h和qcustomplot.cpp文件即可使用,远比qwt方便和漂亮,可以自己 ...

  4. 2.大约QT数据库操作,简单的数据库连接操作,增删改查数据库,QSqlTableModel和QTableView,事务性操作,大约QItemDelegate 代理

     Linux下的qt安装,命令时:sudoapt-get install qt-sdk 安装mysql数据库,安装方法參考博客:http://blog.csdn.net/tototuzuoquan ...

  5. 2.关于QT中数据库操作,简单数据库连接操作,数据库的增删改查,QSqlTableModel和QTableView,事务操作,关于QItemDelegate 代理

     Linux下的qt安装,命令时:sudoapt-get install qt-sdk 安装mysql数据库,安装方法参考博客:http://blog.csdn.net/tototuzuoquan ...

  6. PyQt(Python+Qt)学习随笔:QTableWidgetItem项的复选状态checkState访问方法

    老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 QTableWidget表格部件中的QTableWidgetItem项可以单独设置复选状态,如图所有 ...

  7. C/C++ Qt MdiArea 多窗体组件应用

    MDI多窗体组件,主要用于设计多文档界面应用程序,该组件具备有多种窗体展示风格,其实现了在父窗体中内嵌多种子窗体的功能,使用MDI组件需要在UI界面中增加mdiArea控件容器,我们所有的窗体创建与操 ...

  8. Intent属性详解三 data、type和extra

    1 Data  执行时要操作的数据 在目标<data/>标签中包含了以下几种子元素,他们定义了url的匹配规则: android:scheme 匹配url中的前缀,除了“http”.“ht ...

  9. Qt Creator调试

    与调试器交互的几种方法: 1.单行运行或者单指令运行 2.中断程序运行 3.设置断点 4.检查调用栈空间的内容 5.检查并修改局部或者全局变量 6.检查并修改被调试程序的寄存器和内存内容 7.检查装载 ...

随机推荐

  1. boost.asio学习笔记一、linux下boost库的安装

    欢迎转载,转载请注明原文地址:http://blog.csdn.net/majianfei1023/article/details/46761029 学习开源库第一步就是编译安装好库,然后执行成功一个 ...

  2. Thinkphp错误-phpMyAdmin 尝试连接到 MySQL 服务器,但服务器拒绝连

    phpMyAdmin 尝试连接到 MySQL 服务器,但服务器拒绝连接.您应该检查配置文件中的主机.用户名和密码,并确认这些信息与 MySQL 服务器管理员所给出的信息一致. 原因有可能是因为修改了m ...

  3. Thinkphp学习笔记-模板赋值

    如果要在模板中输出变量,必须在在控制器中把变量传递给模板,系统提供了assign方法对模板变量赋值,无论何种变量类型都统一使用assign赋值. $this->assign('name',$va ...

  4. beyond compare 比较Xls文件时只显示有差异的列

    beyond compare是专业级的文件比较工具,可以比较所有的文件格式,已经成为我工作中的必备软件 在某一个工作项目中需要比较两个Xls文件,两个文件列是相同的,主要是看两个文件的列内容有什么变化 ...

  5. 如何用代码方式获取Web.config中system.serviceModel/client节点的address

    以下代码GetAPIAddress将返回:http://localhost:2555/APITEST.asmx using System.Web.Configuration;using System. ...

  6. RS查询报错之递归公用表表达式不包含顶级 UNION ALL运算符

    在FM里面涉及模型的时候,修改了物理层的查询SQL如下 select * from TARGET_VISIT_GH where ghksdm in(select dept_id from DIM_BI ...

  7. Download Visual Studio

    Welcome to a new way to install Visual Studio! In our newest version, we've made it easier for you t ...

  8. [Node.js] Level 5. Express

    Express Routes Let's create an express route that accepts GET requests on'/tweets' and responds by s ...

  9. C#基础视频教程7.4 如何编写简单游戏

    接下来我们实现整个的游戏流程,当点击开始游戏,则需要三个事情开始运行 1 小鸟初始化并往下掉(当然还是可以用按钮让他飞一下) 2 每隔一定时间从左侧产生一个管子(宽度和高度随机,产生周期2000ms左 ...

  10. Java中equals和==的解析

    java中的数据类型,可分为两类: 1.基本数据类型,也称原始数据类型.byte,short,char,int,long,float,double,boolean   他们之间的比较,应用双等号(== ...