日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Qt系列文章之 QAbstractItemModel(下)

發布時間:2023/12/20 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Qt系列文章之 QAbstractItemModel(下) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

本文緊接著上一文介紹如何對用戶模型剩下的類進行實現,并將其集成到視圖并顯示出來。

QAbstractItemModel

  • insertRows(int row, int count, const QModelIndex &parent)
    該函數實現一次性向表格之中從row位置開始插入count行,一個簡單的實現手段是:
{if(row<0 || row>m_dataVector->size() || count<1) return false;beginInsertRows(parent, row, row + count - 1);for (quint8 i=0;i<count;i++){QPair<QString,int> newPair{};m_dataVector->insert(row+i,newPair);}endInsertRows();return true; }
  • insertColumns(int column, int count, const QModelIndex &parent)
    由于表格固定是兩列,所以此處不做處理。
{beginInsertColumns(parent, column, column + count - 1);endInsertColumns();return false; }
  • removeRows(int row, int count, const QModelIndex &parent)
    刪除行與前面的方法類似,此處一個簡單實現如下:
{if(row<0 || row>m_dataVector->size() || count<1 ) return false;beginRemoveRows(parent, row, row + count - 1);for (quint8 i=0;i<count;i++){if(m_dataVector->size()==0) return true; //判斷是否已經刪除完,如果已完,提前退出m_dataVector->remove(row);}endRemoveRows();return true; }
  • removeColumns(int column, int count, const QModelIndex &parent)
    類似的,此處也不需要對刪除列進行操作:
{beginRemoveColumns(parent, column, column + count - 1);// FIXME: Implement me!endRemoveColumns();return false; }

下一步構造一個簡單的視圖,實現對數據的顯示。進入main.cpp,對前期的界面顯示代碼進行注釋:

int main(int argc, char *argv[]) {QApplication a(argc, argv);// mainWindow w; // w.show();

包含需要的頭文件:

#include <QTableView> #include "customtableview.h"

此處使用標準的QTableView來顯示圖標,構建一個視圖,構建一個用戶模型示例并將其設置為視圖的模型,最后顯示視圖。

QTableView view; //構造視圖CustomItemModel model; //構造模型view.setModel(&model); //設置視圖的模型view.show(); //顯示視圖

編譯運行代碼,顯示表格:

再在用戶模型之中加入一個寫入數據的槽函數:

void CustomItemModel::pushData(QString &name, int &age) {m_dataVector->push_back(QPair<QString,int>(name,age));m_checked.push_back(QPair<bool,bool>(false,false));emit dataChanged(createIndex(m_dataVector->size()-1,0),createIndex(m_dataVector->size()-1,1),QVector<int>() << Qt::DisplayRole<<Qt::CheckStateRole); }

調用對象的槽函數,寫入幾個測試數據:

model.pushData("Jim",28);model.pushData("White",72);

運行模型:

后面我對數據其他一些角色進行修改,增加一個圖標顯示,比如Name列顯示紅色,Age列顯示綠色。

case Qt::DecorationRole://The data to be rendered as a decoration in the form of an icon. (QColor, QIcon or QPixmap){if(index.column()==0) return QColor(255,0,0,255); //Name顯示 紅色if(index.column()==1) return QColor(0,255,0,255); //Age列顯示綠色}

運行代碼:

再給每個條目顯示一個勾選框:

為了方便交互,需要一個數據結構來記錄勾選狀態:

QVector<QPair<bool,bool>> m_checked{}; //儲存某個位置是否被勾選

根據數據設置條目勾選狀態:

case Qt::CheckStateRole:{if(index.column()==0){if(m_checked.at(index.row()).first) return Qt::Checked;else return Qt::Unchecked;}else {if(m_checked.at(index.row()).second) return Qt::Checked;else return Qt::Unchecked;} }

根據用戶選擇記錄勾選狀態:

case Qt::CheckStateRole:{auto cheked = m_checked.at(index.row());if(index.column()==0){m_checked.replace(index.row(),QPair<bool,bool>(value.toBool(),cheked.second));}else{m_checked.replace(index.row(),QPair<bool,bool>(cheked.first,value.toBool()));}emit dataChanged(index, index, QVector<int>() << role);return true;}

為了測試,假設勾選框勾上,設置字體為粗體,如果沒有勾選設置為非粗體。對data之中的FontRole編寫算法如下:

case Qt::FontRole:{QFont font;if(index.column()==0? m_checked.at(index.row()).first:m_checked.at(index.row()).second){font.setBold(true);return font;}else {return font;}}

編譯運行代碼,勾選幾個條目測試代碼效果:

那么需要對insertRows和removeRows做相應的修改。修改后用戶模型的頭文件代碼如下:

#ifndef CUSTOMITEMMODEL_H #define CUSTOMITEMMODEL_H#include <QAbstractItemModel> #include <QVector> #include <QMap>class CustomItemModel : public QAbstractItemModel {Q_OBJECTpublic:explicit CustomItemModel(QObject *parent = nullptr);~CustomItemModel();// Header:QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;bool setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role = Qt::EditRole) override;// Basic functionality:QModelIndex index(int row, int column,const QModelIndex &parent = QModelIndex()) const override;QModelIndex parent(const QModelIndex &index) const override;int rowCount(const QModelIndex &parent = QModelIndex()) const override;int columnCount(const QModelIndex &parent = QModelIndex()) const override;// Fetch data dynamically:bool hasChildren(const QModelIndex &parent = QModelIndex()) const override;bool canFetchMore(const QModelIndex &parent) const override;void fetchMore(const QModelIndex &parent) override;QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;// Editable:bool setData(const QModelIndex &index, const QVariant &value,int role = Qt::EditRole) override;Qt::ItemFlags flags(const QModelIndex& index) const override;// Add data:bool insertRows(int row, int count, const QModelIndex &parent = QModelIndex()) override;bool insertColumns(int column, int count, const QModelIndex &parent = QModelIndex()) override;// Remove data:bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()) override;bool removeColumns(int column, int count, const QModelIndex &parent = QModelIndex()) override;public slots:void pushData(QString,int ); //向模型添加一個數據private:QVector<QPair<QString,int>> *m_dataVector = nullptr; //新建一個儲存數據的序列對象,每個元素(行)兩個值,一個儲存姓名、一個儲存年齡QList<QString> m_headName; //儲存表頭名稱QVector<QPair<bool,bool>> m_checked{}; //儲存某個位置是否被勾選 };#endif // CUSTOMITEMMODEL_H

用戶模型源文件代碼如下:

#include "customitemmodel.h" #include <QDebug> #include <QColor> #include <QFont> #include <iostream>CustomItemModel::CustomItemModel(QObject *parent): QAbstractItemModel(parent),m_dataVector(new QVector<QPair<QString,int>>{}) {m_dataVector->push_back({"Bob",30});m_headName = {"Name","Age"};m_checked.append(QPair<bool,bool>(false,false)); }CustomItemModel::~CustomItemModel() {if(m_dataVector) {m_dataVector->clear();delete m_dataVector;m_dataVector=nullptr;} }QVariant CustomItemModel::headerData(int section, Qt::Orientation orientation, int role) const {if(role!=Qt::DisplayRole)return QVariant();if(orientation==Qt::Vertical)return QVariant(section);if(orientation==Qt::Horizontal){if(section==0) return QVariant(m_headName[0]);if(section==1) return QVariant(m_headName[1]);}return QVariant(); }bool CustomItemModel::setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role) {if (value != headerData(section, orientation, role)) {if(role!=Qt::EditRole) return false;if(orientation==Qt::Vertical) return false;if(section==0) m_headName[0]= value.toString();if(section==1) m_headName[1]=value.toString();emit headerDataChanged(orientation, section, section);return true;}return false; }QModelIndex CustomItemModel::index(int row, int column, const QModelIndex &parent) const {if(row>m_dataVector->size()-1 || row < 0) return QModelIndex();if(column>1 || column<0) return QModelIndex();return createIndex(row,column); }QModelIndex CustomItemModel::parent(const QModelIndex &index) const {// FIXME: Implement me!return QModelIndex(); }int CustomItemModel::rowCount(const QModelIndex &parent) const {return m_dataVector->size(); }int CustomItemModel::columnCount(const QModelIndex &parent) const {return 2; }bool CustomItemModel::hasChildren(const QModelIndex &parent) const {return false; }bool CustomItemModel::canFetchMore(const QModelIndex &parent) const {return false; }void CustomItemModel::fetchMore(const QModelIndex &parent) {// FIXME: Implement me! }QVariant CustomItemModel::data(const QModelIndex &index, int role) const {if (!index.isValid())return QVariant();if(index.row()>m_dataVector->size()-1 || index.row()<0 || index.column()<0 ||index.column()>1)return QVariant();switch(role){case Qt::DisplayRole:{if(index.column()==0){QString name = m_dataVector->at(index.row()).first;return QVariant(name);}if(index.column()==1){int age = m_dataVector->at(index.row()).second;return QVariant(age);}break;}case Qt::TextAlignmentRole:{return Qt::AlignCenter;}case Qt::DecorationRole://The data to be rendered as a decoration in the form of an icon. (QColor, QIcon or QPixmap){if(index.column()==0) return QColor(255,0,0,255); //Name顯示 紅色if(index.column()==1) return QColor(0,255,0,255); //Age列顯示綠色}case Qt::ToolTipRole:{return QVariant();}case Qt::SizeHintRole:{return QVariant();}case Qt::FontRole:{QFont font;if(index.column()==0? m_checked.at(index.row()).first:m_checked.at(index.row()).second){font.setBold(true);return font;}else {return font;}}case Qt::BackgroundRole:{return QVariant();}case Qt::ForegroundRole:{return QVariant();}case Qt::CheckStateRole:{if(index.column()==0){if(m_checked.at(index.row()).first) return Qt::Checked;else return Qt::Unchecked;}else {if(m_checked.at(index.row()).second) return Qt::Checked;else return Qt::Unchecked;}}case Qt::UserRole+1: //用戶自定義角色 預留{return QVariant();}default:return QVariant();} }bool CustomItemModel::setData(const QModelIndex &index, const QVariant &value, int role) {if (data(index, role) != value){switch (role){case Qt::EditRole:{QString name = m_dataVector->at(index.row()).first;int age = m_dataVector->at(index.row()).second;if(index.column()==0){QPair<QString,int> pair(value.toString(),age);m_dataVector->replace(index.row(),pair);}if(index.column()==1){QPair<QString,int> pair(name,value.toInt());m_dataVector->replace(index.row(),pair);}emit dataChanged(index, index, QVector<int>() << role);return true;}case Qt::CheckStateRole:{auto cheked = m_checked.at(index.row());if(index.column()==0){m_checked.replace(index.row(),QPair<bool,bool>(value.toBool(),cheked.second));}else{m_checked.replace(index.row(),QPair<bool,bool>(cheked.first,value.toBool()));}emit dataChanged(index, index, QVector<int>() << role);return true;}default:return false;}}return false; }Qt::ItemFlags CustomItemModel::flags(const QModelIndex &index) const {if (!index.isValid())return Qt::NoItemFlags;return Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemIsSelectable |Qt::ItemIsUserCheckable; // FIXME: Implement me! }bool CustomItemModel::insertRows(int row, int count, const QModelIndex &parent) {if(row<0 || row>m_dataVector->size() || count<1) return false;beginInsertRows(parent, row, row + count - 1);for (quint8 i=0;i<count;i++){QPair<QString,int> newPair{};QPair<bool,bool> state{false,false};m_dataVector->insert(row+i,newPair);m_checked.insert(row+i,state);}endInsertRows();return true; }bool CustomItemModel::insertColumns(int column, int count, const QModelIndex &parent) {beginInsertColumns(parent, column, column + count - 1);endInsertColumns();return false; }bool CustomItemModel::removeRows(int row, int count, const QModelIndex &parent) {if(row<0 || row>m_dataVector->size() || count<1 ) return false;beginRemoveRows(parent, row, row + count - 1);for (quint8 i=0;i<count;i++){if(m_dataVector->size()==0) return true; //判斷是否已經刪除完,如果已完,提前退出m_dataVector->remove(row);m_checked.remove(row);}endRemoveRows();return true; }bool CustomItemModel::removeColumns(int column, int count, const QModelIndex &parent) {beginRemoveColumns(parent, column, column + count - 1);// FIXME: Implement me!endRemoveColumns();return false; }void CustomItemModel::pushData(QString name, int age) {m_dataVector->push_back(QPair<QString,int>(name,age));m_checked.push_back(QPair<bool,bool>(false,false));emit dataChanged(createIndex(m_dataVector->size()-1,0),createIndex(m_dataVector->size()-1,1),QVector<int>() << Qt::DisplayRole<<Qt::CheckStateRole); }

歡迎同好溝通交流,批評指正,歡迎關注我的公號:不如起而行之

總結

以上是生活随笔為你收集整理的Qt系列文章之 QAbstractItemModel(下)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。