zoukankan      html  css  js  c++  java
  • 组合框里添加复选框的方法(使用勾选的假象,用图片代替而已,并非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

  • 相关阅读:
    JavaScipt面向对象编程----闭包
    vmWare虚拟机下ubuntu配置代理上网
    SimpleDateFormat使用具体解释
    同类型结构体之间赋值不一定有效
    EJB究竟是什么,真的那么神奇吗??
    Python学习笔记12:标准库之对象序列化(pickle包,cPickle包)
    android 视频通话开启呼叫等待后,来第三方的视频通话,接通后通话时间一直显示为0,过几秒之后视频通话自己主动挂断
    [Apache Spark源代码阅读]天堂之门——SparkContext解析
    【Linux】linux经常使用基本命令
    白话经典算法系列之中的一个 冒泡排序的三种实现
  • 原文地址:https://www.cnblogs.com/findumars/p/5615694.html
Copyright © 2011-2022 走看看