組合框里添加復選框的方法(使用勾選的假象,用圖片代替而已,並非QT原生支持)


組合框可以看作是列表框和文本框的組合,因其占據的空間少,使用操作方便,常被界面設計人員用於界面開發設計中,在有限個輸入的條件下,組合框常用來代替文本框,這樣從用戶使用角度來看,更趨人性化,所見即所得。然好的控件永遠敢不上應用的步伐,有時常規控件並不能滿足應用的需要,經常需要在現有的控件上做擴展。有些應用需要在組合框的列表框的每一項前加復選框,以便可以控制列表框每一項的狀態(選中還是未選中),顯然現有的組合框(列表框+文本框的組合)不能滿足應用要求。那么怎么得到一個超強組合框(列表框+文本框+復選框的組合)呢?這種組合框既要有一般組合框的功能,又要有復選框的功能。接下來,我將介紹一種在組合框里添加復選框的方法:

先貼出圖,讓大家一睹為快,接下來介紹下它的實現方式,首先看看QComboBox增加項的方法:

[html]  view plain  copy
 
  1. void addItem(const QIcon &icon, const QString &text, const QVariant &userData = QVariant())   

第一個參數在項的前面加圖片,第二個參數是項的名字,第三個參數可以給項一個私有數據,如保存項的狀態。

從addItem方法,第一個參數可以在項前添加圖片,第三個參數可以保存項的狀態,那么我們可以准備兩幅圖片,1幅是沒打鈎的復選框,1幅是打鈎的復選框,用第三個參數來保存復選框的狀態,當第三個參數的狀態為選擇的狀態時,顯示打勾的復選框,否則顯示不打鈎的復選框。看起來這種方法可行,不過要實現復選框功能,還的解決以下幾個問題:

1.當鼠標單擊復選框圖片時,需要計算鼠標是單擊了那一項

2.確定了單擊的項后,還要能取出該項的狀態(通過addItem的第三個參數設置的狀態)

3.再根據項的狀態,更新該項的圖標,並且更改該項的狀態

前面3點實現后,復選框的基本功能就實現了,當鼠標在復選框上單擊時,復選框的圖標就會改變,若之前是選中狀態,則單擊后變為非選中狀態,若之前是非選中狀態,則單擊后變為選中狀態。但是還沒有完,這樣的復選框還是個中看不中用的復選框,還需要給外界提供一個接口,當復選框狀態改變了,要提供1個通知接口,要不然使用該控件的用戶就必須定時輪詢所有的復選框的狀態了,很顯然這不是一個好的設計。

4.當項狀態改變了,還要能對外提供1個項狀態改變的接口。

有了上面的思路,下面來看看實現:

[html]  view plain  copy
 
  1. 頭文件  
  2. #ifndef _CHECK_COMBOX_H  
  3. #define _CHECK_COMBOX_H  
  4.   
  5. #include <qcombobox.h>  
  6. class CCheckCombox : public QComboBox  
  7. {  
  8.     Q_OBJECT  
  9. public:  
  10.     CCheckCombox(QWidget *parent = NULL);  
  11.     void appendItem(const QString &text, bool bChecked);  
  12.     void hidePopup();  
  13.   
  14. protected:  
  15.     void mousePressEvent(QMouseEvent *e);  
  16.   
  17. signals:  
  18.     void checkedStateChange(int index, bool bChecked);  
  19.   
  20. private:  
  21.     void updateIndexStatus(int index);  
  22.   
  23. };  
  24. #endif  

我們定義了1個類CCheckCombox,派生自QComboBox。通過appendItem來給組合框增加項;hidePopup是QComboBox的虛函數,該函數實現組合框的列表框隱藏,我們的目的是,當鼠標單擊列表項前的復選框時,不讓列表框隱藏,只更改復選的圖標,所以需要重載hidePopup;mousePressEvent 是鼠標單擊事件, 這也是父類的的虛函數,重載它是為了確定鼠標是否單擊了復選框,單擊了就要更改復選框狀態;updateIndexStatus大家應該猜到了,該函數就是實現更改項的狀態的函數;checkedStateChange這是一個信號,負責在項狀態改變的時候,發送項狀態改變信號,提供給外界一個應用接口。下面我們來看看實現:

[html]  view plain  copy
 
  1. 源文件  
  2. #include "checkcombox.h"  
  3. #include <QMouseEvent>  
  4. #include <qdebug.h>  
  5. #include <qabstractitemview.h>  
  6. CCheckCombox::CCheckCombox(QWidget *parent) : QComboBox(parent)  
  7. {  
  8.   
  9. }  
  10.   
  11. void CCheckCombox::appendItem(const QString &text, bool bChecked)  
  12. {  
  13.     QIcon icon;  
  14.     if (bChecked)  
  15.         icon.addFile(":/check.png");  
  16.     else  
  17.         icon.addFile(":/uncheck.png");  
  18.     addItem(icon, text, bChecked);  
  19. }  
  20.   
  21. void CCheckCombox::updateIndexStatus(int index)  
  22. {  
  23.     bool bChecked = itemData(index).toBool();  
  24.     if (bChecked)  
  25.         setItemIcon(index, QIcon(":/uncheck.png"));  
  26.     else  
  27.         setItemIcon(index, QIcon(":/check.png"));  
  28.     setItemData(index, !bChecked);  
  29.     emit checkedStateChange(index, !bChecked);  
  30. }  
  31.   
  32. void CCheckCombox::mousePressEvent(QMouseEvent *e)  
  33. {  
  34.     int x = e->pos().x();  
  35.     int iconWidth = iconSize().width();  
  36.     if (x <= iconWidth)  
  37.     {  
  38.         int index = currentIndex();  
  39.         updateIndexStatus(index);  
  40.     }  
  41.     else  
  42.         QComboBox::mousePressEvent(e);  
  43. }  
  44.   
  45. void CCheckCombox::hidePopup()  
  46. {  
  47.     int iconW = iconSize().width();  
  48.     int x = QCursor::pos().x() - mapToGlobal(geometry().topLeft()).x() + geometry().x();  
  49.     int index = view()->selectionModel()->currentIndex().row();  
  50.     if (x >= 0 && x <= iconW)  
  51.     {  
  52.         updateIndexStatus(index);  
  53.     }  
  54.     else  
  55.     {  
  56.         QComboBox::hidePopup();  
  57.     }  
  58. }  

 下面看看應用代碼:

[html]  view plain  copy
 
  1. #include "checkcombox.h"  
  2. int main(int argc, char *argv[])  
  3. {  
  4.     QApplication a(argc, argv);  
  5.     QWidget widget(NULL, Qt::Tool);  
  6.     widget.setWindowTitle("My ComboBox");  
  7.     CCheckCombox combox;  
  8.     QHBoxLayout *phLayout = new QHBoxLayout(&widget);  
  9.     phLayout->addWidget(&combox);  
  10.     widget.setLayout(phLayout);  
  11.     combox.appendItem("1", false);  
  12.     combox.appendItem("2", true);  
  13.     combox.appendItem("3", true);  
  14.     combox.appendItem("4", true);  
  15.     combox.appendItem("5", true);  
  16.     widget.show();  
  17.     return a.exec();  
  18. }  

http://blog.csdn.net/rabinsong/article/details/9007283


免責聲明!

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



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