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下面的。