QComboBox:我们可以让整个组合框都可以点击,而不仅仅是下拉按钮(箭头)本身吗?

QComboBox: Can we make the entire combobox clickable, not just the dropdown button (arrow) itself?

我想在组合框上显示像"Please select one option"这样的文本,而不是在列表中显示文本,所以我将setEditable设置为true,然后将文本设置为lineEdit,但是在此之后,只有下拉按钮(箭头)是可点击的,我们怎样才能让整个组合框都可以点击呢?我正在使用 QComboBox,如下所示:

QComboBox* combbox= new QComboBox;
combbox->setEditable(true);
combbox->lineEdit()->setReadOnly(true);
combbox->addItem("Option1");
combbox->addItem("Option2");
combbox->lineEdit()->setText("Please select one option");

使 QComboBox 可编辑在 UI 方面是有问题的。 我提出了一种不同的方法,重新实现一个 QComboBox 并创建一个默认项,如果用户单击组合框则将其删除:

#include "mycombo.h"

MyCombo::MyCombo(QWidget *parent) :
    QComboBox(parent),
    defaultText_("Please select one option")
{
    addItem(defaultText_);
}

void MyCombo::mousePressEvent(QMouseEvent* event)
{
    if(this->currentText() == defaultText_)
    {
        this->removeItem(0);
    }

    QComboBox::mousePressEvent(event);
}

然后只需创建此组合框并在您想要的位置插入项目

MyCombo *combbox = new MyCombo(this);
combbox->addItem("Option1");
combbox->addItem("Option2");

您可以使用这个库:libqxt

您可以在这里找到它:https://bitbucket.org/libqxt/libqxt/wiki/Home

使用 QxtCheckComboBox 对象,您可以使用它检查 ComboBox 中的多个项目。

我解决了这个问题如下:

class QTComboBoxButton : public QLineEdit
{
    Q_OBJECT
public:
    QTComboBoxButton(QWidget *parent = 0);
    ~QTComboBoxButton();

protected:
    void mousePressEvent(QMouseEvent *);
};

QTComboBoxButton::QTComboBoxButton(QWidget *parent /* = 0 */) :
    QLineEdit(parent)
{
}

QTComboBoxButton::~QTComboBoxButton()
{
}

void QTComboBoxButton::mousePressEvent(QMouseEvent * e)
{
    QComboBox* combo = dynamic_cast<QComboBox*>(parent());
    if(combo)
        combo->showPopup();
}

QComboBox* combbox= new QComboBox;
combbox->setEditable(true);
combbox->setLineEdit(new QTComboBoxButton(combbox));
combbox->lineEdit()->setReadOnly(true);
combbox->addItem("Option1");
combbox->addItem("Option2");
combbox->lineEdit()->setText("Please select one option");

IdlChina 的回答有一个缺点:当你点击已经显示的组合框时,它会隐藏并立即再次显示。我有一个稍微不同的方法,没有这个问题。

class ButtonComboBox : public QComboBox
{
public:
    ButtonComboBox(QWidget *parent = nullptr)
        : QComboBox(parent),
          _isPopupShown(false),
          _timer(new QTimer(this))
    {
        auto lineEdit = new QLineEdit;
        lineEdit->installEventFilter(this);
        setLineEdit(lineEdit);

        _timer->setSingleShot(true);
        _timer->setInterval(100);
    }

protected:
    bool eventFilter(QObject *object, QEvent *event) override
    {
        if (object == lineEdit() && event->type() == QEvent::MouseButtonPress) {
            if (!_timer->isActive()) {
                if (!_isPopupShown)
                    showPopup();
                else if (_isPopupShown)
                    hidePopup();

                return true;
            }
        }

        return false;
    }

    void showPopup() override
    {
        QComboBox::showPopup();
        _isPopupShown = true;
        _timer->start();
    }

    void hidePopup() override
    {
        QComboBox::hidePopup();
        _isPopupShown = false;
        _timer->start();
    }

private:
    bool _isPopupShown;
    QTimer *_timer;
};