简述

在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. PHP实现双向链表、栈

    前期写过一个PHP实现单向链表.实现排序单向链表的一篇文章,传送门:http://www.cnblogs.com/yydcdut/p/3777760.html.双向链表写过了,再拿出来提一提:http ...

  2. BI项目简单备份策略

    在项目的开发中,备份是一个很重要的操作和良好的开发习惯,下面我们就针对BI相关项目的备份说一下备份策略 前端:Cognos 后端:SSIS+View+Procedure 服务器A装了Cognos内容库 ...

  3. SSIS实践入门2:批量包的调度和SQLServer代理作业配置

    趁着上一篇文章的余温,我们继续研究一下SSIS中多个包如何调度,难道需要一个包一个包的配置调度程序吗?显然不是的,接下来我们就说一说在SSIS应用中如何批量的调度所有的作业,本文只讲述一个基本的逻辑过 ...

  4. html中嵌入flvplayer.swf播放器,播放视频

    只需要改动红色的代码: <object classid='clsid:D27CDB6E-AE6D-11cf-96B8-4445535411111' codebase='http://downlo ...

  5. es5 - array - unshift

    /** * 描述:该unshift()方法从数组中添加单个或多个元素,并且返回长度 * 语法:arr.unshift(element1 [,... [,elementN ]]) * 参数:要添加到数组 ...

  6. spring测试实例

    我们以前要进行单元测试,必须先得到ApplicationContext对象,再通过它得到业务对象,非常麻烦,重复代码也多.基于spring3的单元测试很好的解决了这个问题 基于spring3的单元测试 ...

  7. findlibrary returned null产生的联想,Android ndk开发打包时我们应该怎样注意平台的兼容(x86,arm,arm-v7a)

    非常多朋友在开发Android JNI的的时候,会遇到findlibrary returned null的错误,由于某种原因,so没有打包到apk中.以下浅析下引起该错误的原因以及平台兼容性问题. A ...

  8. 解决在sdk manager中更新文件后出现This Android SDK requires Android Developer Toolkit version 23.1的错误

    起因:在sdksdk manager中更新了adt及其它的支持库后,eclipse报错:This Android SDK requires Android Developer Toolkit vers ...

  9. xtrabackup备份方式搭建一个mysql slave

    以前mysql搭建新备库都是在现在业务较小的备库上停止同步或停止数据库,然后拷贝数据库到新备库,配置好新备库后,再开启同步或数据库.然而,这次没有空闲备库用来搭新备库.需要从一个业务繁忙的数据库中搭建 ...

  10. Android Launcher拖拽事件详解【android4.0--Launcher系列二】

    AndroidICS4.0版本的launcher拖 拽的流程,基本和2.3的相似.就是比2.3写的封装的接口多了一些,比如删除类的写法就多了个类.等等.4.0的改变有一些,但是不是特别大.这个月一 直 ...