Qt之界面數據存儲與獲取(使用setUserData()和userData())


在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)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

其中,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);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

槽函數,獲取用戶數據,執行相應操作。

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; }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

整體存儲

也可以通過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);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

槽函數,獲取用戶數據,執行相應操作。

void onItemClicked(QListWidgetItem *item) { QVariant variant = item->data(Qt::UserRole); // 獲取用戶數據 User user = variant.value<User>(); qDebug() << "ID : " << user.nID; qDebug() << "Name : " << user.strName; }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

無論那種方式都可以,如果在信號和槽的傳遞過程中,參數過多,建議使用“整體存儲”方式。

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);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

槽函數,獲取用戶數據,執行相應操作。

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; }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

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);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

槽函數,獲取用戶數據,執行相應操作。

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; }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

通過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; };
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35

我們定義了一個按鈕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);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

槽函數,獲取用戶數據,執行相應操作。

void onClicked() { // 獲取發送者 QObject *pObject = this->sender(); PushButton *pButton = qobject_cast<PushButton *>(pObject); // 獲取用戶數據 qDebug() << "ID : " << pButton->id(); qDebug() << "Name : " << pButton->name(); }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

基本的數據存儲與獲取方式就這些,以后會經常用到,Good luck。

 

http://blog.csdn.net/u011012932/article/details/52413012


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM