qt自定义下拉菜单框

Qt自带的QCombBox下拉能够显示的东西有限,想添加其他的控件不太方便,所以就想自己定义一个,基本思路是,一个QLineEdit,一个QPushButton,一个QListWidget组成一个组合控件。

过程:

1、将QPushButton嵌入进QLineEdit中。

_button->setText("...");

_lineEdit->setReadOnly(true);
_lineEdit->setAlignment(Qt::AlignCenter);
_lineEdit->setText("test");
this->_lineEdit->setMaximumWidth(100);

QVBoxLayout* mainLayout = new QVBoxLayout(this);
mainLayout->addWidget(this->_lineEdit);

QWidgetAction* widgetAction = new QWidgetAction(this->_lineEdit);
widgetAction->setDefaultWidget(this->_button);
_lineEdit->addAction(widgetAction, QLineEdit::TrailingPosition);

2、绑定按钮信号槽

connect(_button, &QPushButton::clicked, this, &DLevitaComboBox::on_buttonClicked);

这里没有对按键实施按下检查,是为了将来在其他条件下需要收回下拉菜单时,操作起来更加方便。直接调用相关的槽函数即可。

3、编写槽函数

void DLevitaComboBox::on_buttonClicked()
{
    _check = !_check; //初始化为false
    int widgetStartX = this->mapToGlobal(QPoint(0, 0)).x();
    int widgetStartY = this->mapToGlobal(QPoint(0, 0)).y() + this->height();
    int widgetStartWidth = _width;
    int widgetStartHeight = _height;

    QRect startRect(widgetStartX, widgetStartY, widgetStartWidth, widgetStartHeight);
    QRect endRect(widgetStartX, widgetStartY, widgetStartWidth, 0);

    if (_check)
    {
        QRect temp;
        temp = endRect;
        endRect = startRect;
        startRect = temp;
    }

    QPropertyAnimation* animation = new QPropertyAnimation(_widget, "geometry");
    animation->setStartValue(startRect);
    animation->setEndValue(endRect);
    QObject::connect(animation, &QPropertyAnimation::finished, this, [=]() {
        if (!_check)
        {
            _widget->setVisible(true);
        }
        _widget->raise();
        });
    _widget->setVisible(true);
    animation->start(QAbstractAnimation::DeletionPolicy::DeleteWhenStopped);
}

槽函数中使用动画类实现widget的收缩。

4、设置QListWidget

原本计划是使用一个widget来创建下拉框,但尝试后未能成功,原因不明。因此,我改用了一个QListWidget来替代,并且需要对这个QListWidget进行一系列设置,以便它能像widget那样工作。

_widget->setParent(this); //widget就是QListWidget
_widget->setVisible(false);
_widget->setWindowFlags(Qt::Tool | Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint);

QListWidgetItem* pItem = new QListWidgetItem();
QWidget* mainWidget = new QWidget();

pItem->setSizeHint(QSize(_width, _height));
_widget->addItem(pItem);
_widget->setItemWidget(pItem, mainWidget);
_widget->horizontalScrollBar()->hide(); //隐藏横向滚动条
_widget->setStyleSheet(
    "QListWidget{"
    "    color: gray;"
    "    font-size: 12px;"
    "    background: #FAFAFD;"
    "    outline: 0; /* 去除焦点时的虚线框 */"
    "}"
    "QListWidget::item {"
    "    border: none; /* 取消边框 */"
    "    padding: 2px; /* 可选的内边距 */"
    "}"
    "QListWidget::item:selected {"
    "    background: none; /* 取消选中背景 */"
    "}"
    "QScrollBar{"
    "    width: 0;"
    "    height: 0;"
    "}"
);

_widget->setSelectionMode(QAbstractItemView::NoSelection);

效果演示:

效果演示

这里空隙太大是因为这个Widget中只有一个QLineEdit,而且我限定了这个QLineEdit的大小,实际使用中这个下拉框是紧贴在QLineEdit下面的。

你可能感兴趣的:(qt)