1. 程式人生 > >Delegate 類 概念 與MVC模式不同,model/view結構沒有用於與使用者互動的完全獨立的元件。一般來講, view負責把資料展示給使用者,也處理使用者的輸入。為了獲得更多的靈性性,互動通過d

Delegate 類 概念 與MVC模式不同,model/view結構沒有用於與使用者互動的完全獨立的元件。一般來講, view負責把資料展示給使用者,也處理使用者的輸入。為了獲得更多的靈性性,互動通過d

Delegate  類

概念 MVC模式不同,model/view結構沒有用於與使用者互動的完全獨立的元件。一般來講, view負責把資料展示給使用者,也處理使用者的輸入。為了獲得更多的靈性性,互動通過delegagte執行。它既提供輸入功能又負責渲染view中的每個資料項。使用Delegate的原因  Qt中當用到QTreeView和QTableView等用於顯示item的檢視時,你要編輯一個item用到的編輯工具可能是除了預設文字編輯lineEdit以外的工具,例如button,spinBox,甚至Slider,ProgressBar,也有可能是自定義的widget。所以Qt提供了一個委託類,用來處理View中的資料展示方式。

Delegate類的繼承架構見下圖,

        自從Qt4.4,出現了兩個delegate基類,QStyledItemDelegate vs. QItemDelegate。預設的delegate是QStyledItemDelegate,即你不自己寫delegate的時候,預設那個lineEdit是來自QStyledItemDelegate。Qt Assistant建議使用者如果自定義delegate或者用到了Qt style sheets的話,最好繼承自QStyledItemDelegate,為什麼呢?首先這兩個類在繪製代理和為item提供編輯器上面是獨立的,沒什麼聯絡,互不影響;不同的是QStyledItemDelegate使用當前style來繪製item(的代理),即如果程式設定了總體的風格(用QSS或其他定義方式),QStyledItemDelegate會使用這個風格設定。

先看看Qt Demos看了裡面spinboxDelegat的例子:
1. 自定義的delegate繼承自QItemDelegate。

2. 必須過載的一些函式:
       (1)  QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option,const QModelIndex &index) const;
       (2)  void setEditorData(QWidget *editor, const QModelIndex &index) const;
       (3)  void setModelData(QWidget *editor, QAbstractItemModel *model,const QModelIndex &index) const;
       (4)  void updateEditorGeometry(QWidget *editor,const QStyleOptionViewItem &option, const QModelIndex &index) const;

3. createEditor建立自定義widget並返回之。
        setEditorData是將model中當前有的資料設定到代理上。自己從model取出資料,自己setValue到editor上。
        setModelData是將editor上的資料儲存到Model中。
        updateEditorGeometry就是將editor設定到一定位置,並且有一定大小,使這個editor看起來像是正好嵌入到格子裡面一樣。用的是option.rect。

4. closeEditor() signal 表明使用者完成編輯資料,編輯控制元件可以銷燬。

5. commitData() signal 必須在完成編輯資料之後,傳送該訊號,將會把新資料寫回Model

6. paint() and sizeHint(), QitemDelegate預設繼承了該方法,如果需要特殊風格繪製單元項中內容,還需過載這兩個函式。

一、

   SpinBoxDelegate例子是Qt Assistant中提供的一個非常優秀的例子,雖然講的是繼承於QItemDelegate的例子。但對於我們理解Delegate-委託這個概念,非常有幫助。

它過載了必須的幾個函式:

        (1)  QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option,const QModelIndex &index) const;
       (2)  void setEditorData(QWidget *editor, const QModelIndex &index) const;
       (3)  void setModelData(QWidget *editor, QAbstractItemModel *model,const QModelIndex &index) const;
       (4)  void updateEditorGeometry(QWidget *editor,const QStyleOptionViewItem &option, const QModelIndex &index) const;

下面把原始碼附上,並加上部分註釋。附件有原始碼可以下載。

Main.cpp

Cpp程式碼  收藏程式碼
  1. #include <QApplication>  
  2. #include <QHeaderView>  
  3. #include <QItemSelectionModel>  
  4. #include <QStandardItemModel>  
  5. #include <QTableView>  
  6. #include "delegate.h"  
  7. int main(int argc, char *argv[])  
  8. {  
  9.     QApplication app(argc, argv);  
  10.     //構建一個4行,2列的項模型  
  11.     QStandardItemModel model(4, 2);  
  12.     //宣告一個TableView  
  13.     QTableView tableView;  
  14.     //繫結模型  
  15.     tableView.setModel(&model);  
  16.     //宣告一個委託  
  17.     SpinBoxDelegate delegate;  
  18.     //設定檢視的委託  
  19.     tableView.setItemDelegate(&delegate);  
  20.     //ensuring that the view does not waste any of the space assigned to it for its header  
  21.     //最後一列全部填充View  
  22.     tableView.horizontalHeader()->setStretchLastSection(true);  
  23.     //初始化Model  
  24.     for (int row = 0; row < 4; ++row) {  
  25.         for (int column = 0; column < 2; ++column) {  
  26.             QModelIndex index = model.index(row, column, QModelIndex());  
  27.             model.setData(index, QVariant((row+1) * (column+1)));  
  28.         }  
  29.     }  
  30.     tableView.setWindowTitle(QObject::tr("Spin Box Delegate"));  
  31.     tableView.show();  
  32.     return app.exec();  
  33. }  

 delegate.h

Cpp程式碼  收藏程式碼
  1. #ifndef DELEGATE_H  
  2. #define DELEGATE_H  
  3. #include <QItemDelegate>  
  4. #include <QModelIndex>  
  5. #include <QObject>  
  6. #include <QSize>  
  7. #include <QSpinBox>  
  8. class SpinBoxDelegate : public QItemDelegate  
  9. {  
  10.     Q_OBJECT  
  11. public:  
  12.     SpinBoxDelegate(QObject *parent = 0);  
  13.     //返回一個編輯控制元件,用來編輯指定項的資料  
  14.     QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option,  
  15.                           const QModelIndex &index) const;  
  16.     //將Model中資料賦值到控制元件上  
  17.     void setEditorData(QWidget *editor, const QModelIndex &index) const;  
  18.     //設定模型資料,根據指定項中對應編輯控制元件的資料  
  19.     void setModelData(QWidget *editor, QAbstractItemModel *model,  
  20.                       const QModelIndex &index) const;  
  21.     //更新編輯框幾何形狀  
  22.     void updateEditorGeometry(QWidget *editor,  
  23.         const QStyleOptionViewItem &option, const QModelIndex &index) const;  
  24. };  
  25. #endif  

 delegate.cpp

Cpp程式碼  收藏程式碼
  1. #include <QtGui>  
  2. #include "delegate.h"  
  3. SpinBoxDelegate::SpinBoxDelegate(QObject *parent)  
  4.     : QItemDelegate(parent)  
  5. {  
  6. }  
  7. //返回一個編輯控制元件,用來編輯指定項的資料  
  8. QWidget *SpinBoxDelegate::createEditor(QWidget *parent,  
  9.     const QStyleOptionViewItem &/* option */,  
  10.     const QModelIndex &/* index */const  
  11. {  
  12.     //返回該QSpinBox控制元件  
  13.     QSpinBox *editor = new QSpinBox(parent);  
  14.     editor->setMinimum(0);  
  15.     editor->setMaximum(100);  
  16.     return editor;  
  17. }  
  18. //將Model中資料賦值到控制元件上  
  19. void SpinBoxDelegate::setEditorData(QWidget *editor,  
  20.                                     const QModelIndex &index) const  
  21. {  
  22.     //返回該索引的模型,繼而返回該模型中此索引的編輯角色資料  
  23.     int value = index.model()->data(index, Qt::EditRole).toInt();  
  24.     //給控制元件賦值  
  25.     QSpinBox *spinBox = static_cast<QSpinBox*>(editor);  
  26.     spinBox->setValue(value);  
  27. }  
  28. //設定模型資料,根據指定項中對應編輯控制元件的資料  
  29. void SpinBoxDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,  
  30.                                    const QModelIndex &index) const  
  31. {  
  32.     QSpinBox *spinBox = static_cast<QSpinBox*>(editor);  
  33.     spinBox->interpretText();  
  34.     int value = spinBox->value();  
  35.     //設定模型的資料  
  36.     model->setData(index, value, Qt::EditRole);  
  37. }  
  38. //更新編輯框幾何形狀  
  39. void SpinBoxDelegate::updateEditorGeometry(QWidget *editor,  
  40.     const QStyleOptionViewItem &option, const QModelIndex &/* index */const  
  41. {  
  42.     //根據option,設定編輯框位置  
  43.     editor->setGeometry(option.rect);  
  44. }  
  45. 二、
  46.  trackeEditorDelegate例子是《C++ GUI Programming with Qt 4》中自定義委託的標準例子。

    和上一個SpinBox例子相比更完整:它多了自定義Editor、過載Paint()函式、提交資料訊號commitData()、關閉控制元件訊號closeEditor()

    附件中有原始碼可以下載。

    Main.cpp

    Cpp程式碼  收藏程式碼
    1. #include <QApplication>  
    2. #include "trackeditor.h"  
    3. int main(int argc, char *argv[])  
    4. {  
    5.     QApplication app(argc, argv);  
    6.     QList<Track> tracks;  
    7.     tracks << Track("The Flying Dutchman: Overture", 630)  
    8.            << Track("The Flying Dutchman: Wie aus der Fern laengst "  
    9.                     "vergangner Zeiten", 374)  
    10.            << Track("The Flying Dutchman: Steuermann, lass die Wacht",  
    11.                     152)  
    12.            << Track("Die Walkuere: Ride of the Valkyries", 286)  
    13.            << Track("Tannhaeuser: Freudig begruessen wir die edle "  
    14.                     "Halle", 384)  
    15.            << Track("Tannhaeuser: Wie Todesahnung - O du mein holder "  
    16.                     "Abendstern", 257)  
    17.            << Track("Lohengrin: Treulich gefuert ziehet dahnin", 294)  
    18.            << Track("Lohengrin: In fernem Land", 383)  
    19.            << Track("Die Meistersinger von Nuernberg: Overture", 543)  
    20.            << Track("Die Meistersinger von Nuernberg: Verachtet mir "  
    21.                     "die Meister nicht", 200)  
    22.            << Track("Die Meistersinger von Nuernberg: Ehrt eure "  
    23.                     "deutschen Meister", 112)  
    24.            << Track("Goetterdaemmerung: Funeral Music", 469)  
    25.            << Track("Tristan und Isolde: Mild und leise, wie er "  
    26.                     "laechelt", 375);  
    27.     //自定義編輯控制元件  
    28.     TrackEditor editor(&tracks);  
    29.     editor.resize(600, 300);  
    30.     editor.show();  
    31.     return app.exec();  
    32. }  

     TrackEditor.h

    Cpp程式碼  收藏程式碼
    1. #ifndef TRACKEDITOR_H  
    2. #define TRACKEDITOR_H  
    3. #include <QDialog>  
    4. #include <QList>  
    5. class QDialogButtonBox;  
    6. class QTableWidget;  
    7. class Track  
    8. {  
    9. public:  
    10.     Track(const QString &title = ""int duration = 0);  
    11.     QString title;  
    12.     int duration;  
    13. };  
    14. 相關推薦

      Delegate 概念 MVC模式不同model/view結構沒有用於使用者互動完全獨立元件一般來講 view負責資料展示使用者處理使用者的輸入為了獲得靈性互動通過d

      Delegate  類 概念 與MVC模式不同,model/view結構沒有用於與使用者互動的完全獨立的元件。一般來講, view負責把資料展示給使用者,也處理使用者的輸入。為了獲得更多的靈性性,互動通過delegagte執行。它既提供輸入功能又負責渲染view中的每個

      MySQL 服務正在啟動MSQL服務無法啟動服務沒有報告任何錯誤請鍵入NET HELPMSG 3534 以獲得的幫助(雙系統修復二)

      因為我以前下過mysql,所以這次懶得在官網重新下載,因此碰到了不少的麻煩。 1.通過DOS視窗輸入net start mysql時,卻提示服務名無效 解決方案: (1)首先我們先進入mysql的安裝

      cmd中輸入net start mysql 提示:服務名無效 請鍵入NET HELPING 2185以獲得的幫助

      服務列表裡沒有MySQL服務,故出現該錯誤。請進入MySQL的bin目錄,並在bin目錄開啟命令列視窗,在命令列視窗輸入:mysqld --install,回車,提示:Service successfully installed。表示安裝MySQL服務成功,命令列視窗輸入:

      net start mysql; 服務名無效 請鍵入 NET HELPMSG 2185 以獲得的幫助

      提示:請仔細閱讀標題!!!! 我的根本問題在於命令本身錯誤:【在命令結尾加了“分號”!】 啟動或停止MySQL資料庫服務,以及資料庫備份、恢復等命令,在沒有登入MySQL系統時,結尾是不需要以“”分號

      重灌系統導致的問題" cmd中輸入net start mysql 提示:服務名無效 請鍵入NET HELPING 2185以獲得的幫助 "

      問題描述: 筆記本作業系統重灌,雖然Mysql資料庫並沒有安裝在c盤下,但是發現服務列表中的mysql服務不見了,所以在cmd下啟動mysql服務時不能成功並提示標題中的錯誤資訊. 解決辦法: 進

      Mysql錯誤:服務名無效 請鍵入 NET HELPMSG 2185 以獲得的幫助

      前言 在練習使用Python呼叫MYsql的過程中,首先是安裝MYsql,然後在安裝MYsql過程中,遇到了上述問題: D:\program\mysql\mysql-8.0.11-winx64\bin>net start mysql1 服務

      畢業是為了遇見好的你願你不再停留

      遇到 學院 大神 是你 會有 同學 貴的 我會 實的 不見君子,風雨如晦。華科你好,很高興你陪我走過這幾年,從青澀到成熟。 很高興遇到你們。有傷感,因為可能有些人從此就再也見不到一面,只能聽到電流和成的聲音。但是也沒有太多傷感,因為大家都會有更好的前程和更充實的生活。是你

      【 MATLAB 】使用 MATLAB 得到高密度譜(補零得到DFT)和高解析度譜(獲得資料得到DFT)的方式對比(附MATLAB指令碼)

      那篇博文中,我們通過補零的方式來增加N,這樣最後的結論是隨著N的不斷增大,我們只會得到DTFT上的更多的取樣點,也就是說頻率取樣率增加了。通過補零,得到高密度譜(DFT),但不能得到高解析度譜,因為

      【xu的blog】有壓力就有的動力無壓力將有的創新

      專欄達人 授予成功建立個人部落格專欄

      angularjs學習筆記三——AngularJSMVC模式

      本文主要解決一下幾個問題: 什麼是MVCMVC優點缺點AngularJS的MVC是怎樣的來個簡單的示例 一、什麼是MVC        MVC模式非常重要,無論你是B/S還是C/S的開發者(實際上個人認為B/S也是C/S的一種特殊形式),甚至你是純Client或Browse

      三層架構mvc模式

      什麼是三層架構? 三層架構由使用者介面層/表示層(User Interface),業務邏輯層(Business Logic Layer)和資料訪問層(Data Acess Layer)構成。 其中每一層的作用為: 使用者介面層:負責與使用者進行互動。 業務邏輯層:主要

      MySQL解壓包安裝請鍵入 NET HELPMSG 3534 以獲得的幫助

      出現異常,解決異常全過程如下圖: 異常及解決全過程程式碼如下: C:\Program Files\MySQL\mysql-8.0.12-winx64\bin>net start mysql My

      MVP模式MVC模式(轉)

      MVP 是從經典的模式MVC演變而來,它們的基本思想有相通的地方:Controller/Presenter負責邏輯的處理,Model提供資料,View負責顯示。作為一種新的模式,MVP與MVC有著一個重大的區別:在MVP中View並不直接使用Model,它們之間的通訊是通過

      mysql-5.7.10-winx64 MySQL服務無法啟動服務沒有報告任何錯誤請鍵入 NET HELPMSG 3534 以獲得的幫助

      我在Oracle官網mysql-5.7.10-winx64的tar的版本(非安裝版),解壓後發現沒有data資料夾,於是在mysql-5.7.10-winx64下自己手動新建了data目錄,並寫入了人my.ini的檔案 datadir=D:\Program Files\my

      淺談Android中MVP模式MVC模式的區別

      一、概述 對於MVP(Model View Presenter),大多數人都能說出一二:“MVC的演化版本”,“讓Model和View完全解耦”等等。本篇博文僅是為了做下記錄,提出一些自己的看法,和幫助大家如何針對一個Activity頁面去編寫針對MVP風

      mysql 5.7安裝報錯: 請鍵入 NET HELPMSG 3534 以獲得的幫助

      本地顯示安裝了5.5版本,後來在執行sql指令碼的時候報錯,原因是由於5.5不支援兩個欄位為timestamp型別,沒有具體分析原因,就解除安裝了5.5版本。網上隨便下載了一個5.7的mysql,安裝後,使用command client啟動發現閃退,找到原因是,

      [轉貼]為了獲得有尊嚴的生活你必須在年輕時學會賺錢

      發現很多朋友創業的心裡很矛盾,既有創業單幹的ji情,同時又有擔心失敗後悲慘的命運!  所以很多朋友思考了很長時間,最後還是決定等等再看,一月過了一月,一年過了又一年,歲月流逝,光陰不再,沉浸在打工的生涯中難以自拔,結婚供房,身上的經濟枷鎖日益沉重,無力再搏,最後只好認命,打工一輩子。    中國溫州人號稱中國

      關於抖音如何熱門怎麼上推薦獲取的流量獲取的抖音粉絲

      抖音如何上熱門?自然漲粉絲,抖音直播教程技巧 抖音已經成為當下年輕人最喜愛的短視訊軟體,不知道愛拍攝短視訊的你知道抖音怎麼上熱門,抖音如何“刷”粉絲嗎?抖音刷粉絲最好的方法你的抖音視訊就是上熱門,得到官方的推薦。 1.原創優質的抖音視訊 2.點贊量=使用者

      前臺通過js 寫個ajax請求資料後臺然後後臺接收到這個資料 再儲存到資料庫

       //前端js操作: function testAjax(){ var url="/testAjaxUrlJson/";//後臺接收處理url var txtContent= "textprm";//傳輸內容;  var objData = [         { name

      Android 瀑布流遇到的各種問題(item移動載入圖片閃爍以及定製各種型別Header和Footer)

      轉載地址:http://blog.csdn.net/windows771053651/article/details/51596744 功能:圖片瀑布流 問題1:如何保持已顯示過的imageview的尺寸 解決方法:定義一個HashMap<Integer,