组合框里添加复选框的方法

组合框可以看作是列表框和文本框的组合,因其占据的空间少,使用操作方便,常被界面设计人员用于界面开发设计中,在有限个输入的条件下,组合框常用来代替文本框,这样从用户使用角度来看,更趋人性化,所见即所得。然好的控件永远敢不上应用的步伐,有时常规控件并不能满足应用的需要,经常需要在现有的控件上做扩展。有些应用需要在组合框的列表框的每一项前加复选框,以便可以控制列表框每一项的状态(选中还是未选中),显然现有的组合框(列表框+文本框的组合)不能满足应用要求。那么怎么得到一个超强组合框(列表框+文本框+复选框的组合)呢?这种组合框既要有一般组合框的功能,又要有复选框的功能。接下来,我将介绍一种在组合框里添加复选框的方法:

先贴出图,让大家一睹为快,接下来介绍下它的实现方式,首先看看QComboBox增加项的方法:

void addItem(const QIcon &icon, const QString &text, const QVariant &userData = QVariant()) 

第一个参数在项的前面加图片,第二个参数是项的名字,第三个参数可以给项一个私有数据,如保存项的状态。

从addItem方法,第一个参数可以在项前添加图片,第三个参数可以保存项的状态,那么我们可以准备两幅图片,1幅是没打钩的复选框,1幅是打钩的复选框,用第三个参数来保存复选框的状态,当第三个参数的状态为选择的状态时,显示打勾的复选框,否则显示不打钩的复选框。看起来这种方法可行,不过要实现复选框功能,还的解决以下几个问题:

1.当鼠标单击复选框图片时,需要计算鼠标是单击了那一项

2.确定了单击的项后,还要能取出该项的状态(通过addItem的第三个参数设置的状态)

3.再根据项的状态,更新该项的图标,并且更改该项的状态

前面3点实现后,复选框的基本功能就实现了,当鼠标在复选框上单击时,复选框的图标就会改变,若之前是选中状态,则单击后变为非选中状态,若之前是非选中状态,则单击后变为选中状态。但是还没有完,这样的复选框还是个中看不中用的复选框,还需要给外界提供一个接口,当复选框状态改变了,要提供1个通知接口,要不然使用该控件的用户就必须定时轮询所有的复选框的状态了,很显然这不是一个好的设计。

4.当项状态改变了,还要能对外提供1个项状态改变的接口。

有了上面的思路,下面来看看实现:

头文件
#ifndef _CHECK_COMBOX_H
#define _CHECK_COMBOX_H

#include <qcombobox.h>
class CCheckCombox : public QComboBox
{
    Q_OBJECT
public:
    CCheckCombox(QWidget *parent = NULL);
    void appendItem(const QString &text, bool bChecked);
    void hidePopup();

protected:
    void mousePressEvent(QMouseEvent *e);

signals:
    void checkedStateChange(int index, bool bChecked);

private:
    void updateIndexStatus(int index);

};
#endif

我们定义了1个类CCheckCombox,派生自QComboBox。通过appendItem来给组合框增加项;hidePopup是QComboBox的虚函数,该函数实现组合框的列表框隐藏,我们的目的是,当鼠标单击列表项前的复选框时,不让列表框隐藏,只更改复选的图标,所以需要重载hidePopup;mousePressEvent 是鼠标单击事件, 这也是父类的的虚函数,重载它是为了确定鼠标是否单击了复选框,单击了就要更改复选框状态;updateIndexStatus大家应该猜到了,该函数就是实现更改项的状态的函数;checkedStateChange这是一个信号,负责在项状态改变的时候,发送项状态改变信号,提供给外界一个应用接口。下面我们来看看实现:

源文件
#include "checkcombox.h"
#include <QMouseEvent>
#include <qdebug.h>
#include <qabstractitemview.h>
CCheckCombox::CCheckCombox(QWidget *parent) : QComboBox(parent)
{

}

void CCheckCombox::appendItem(const QString &text, bool bChecked)
{
    QIcon icon;
    if (bChecked)
        icon.addFile(":/check.png");
    else
        icon.addFile(":/uncheck.png");
    addItem(icon, text, bChecked);
}

void CCheckCombox::updateIndexStatus(int index)
{
    bool bChecked = itemData(index).toBool();
    if (bChecked)
        setItemIcon(index, QIcon(":/uncheck.png"));
    else
        setItemIcon(index, QIcon(":/check.png"));
    setItemData(index, !bChecked);
    emit checkedStateChange(index, !bChecked);
}

void CCheckCombox::mousePressEvent(QMouseEvent *e)
{
    int x = e->pos().x();
    int iconWidth = iconSize().width();
    if (x <= iconWidth)
    {
        int index = currentIndex();
        updateIndexStatus(index);
    }
    else
        QComboBox::mousePressEvent(e);
}

void CCheckCombox::hidePopup()
{
    int iconW = iconSize().width();
    int x = QCursor::pos().x() - mapToGlobal(geometry().topLeft()).x() + geometry().x();
    int index = view()->selectionModel()->currentIndex().row();
    if (x >= 0 && x <= iconW)
    {
        updateIndexStatus(index);
    }
    else
    {
        QComboBox::hidePopup();
    }
}

 下面看看应用代码:

#include "checkcombox.h"
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QWidget widget(NULL, Qt::Tool);
    widget.setWindowTitle("My ComboBox");
    CCheckCombox combox;
    QHBoxLayout *phLayout = new QHBoxLayout(&widget);
    phLayout->addWidget(&combox);
    widget.setLayout(phLayout);
    combox.appendItem("1", false);
    combox.appendItem("2", true);
    combox.appendItem("3", true);
    combox.appendItem("4", true);
    combox.appendItem("5", true);
    widget.show();
    return a.exec();
}



 

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

RabinSong

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值