详细代码如下:
//下拉框风格初始化
void comboBoxInit(QComboBox*box,int widthScroll=25,int height=30,bool bSheet=false);
//下拉框风格初始化
void comboBoxInit(QComboBox*box,int widthScroll,int height,bool bSheet)
{
//显示居中
QLineEdit*lineEdit = box->lineEdit();
if(lineEdit == 0)
{
lineEdit = new QLineEdit(box);
lineEdit->setObjectName("lintEditAdptive");
lineEdit->setReadOnly(true);
lineEdit->setAlignment(Qt::AlignCenter);
lineEdit->setFocusPolicy(Qt::NoFocus);
QLineEdit::connect(lineEdit,&QLineEdit::selectionChanged,[=]{
lineEdit->deselect();
box->showPopup();
});
QComboBox::connect(box,&QComboBox::currentTextChanged,[=](const QString &text){
for(int i = 0; i < box->count(); i++)
{
if(box->itemText(i) == text)
{
box->setCurrentIndex(i);
break;
}
}
});
box->setLineEdit(lineEdit);
}
if(bSheet)//是否设置样式
{
QString sheet = QString("QComboBox{\
margin:2px;\
background: rgba(0,0,0,0);\
border: 1px solid #C0C4CC;\
border-radius: 4px;\
padding-left:%2px;\
}QComboBox::drop-down {width:%2px;}\
QComboBox QAbstractItemView {background-color:rgba(255, 255, 255, 255);}\
QComboBox QAbstractItemView::item {height: %1px;}\
QComboBox QAbstractScrollArea QScrollBar:vertical { width: %2px; }")
.arg(height).arg(widthScroll);
box->setStyleSheet(sheet);
box->setView(new QListView());
//因为透明的,所以设置一个widget做背景
QString objectName = box->objectName()+"Widget";
QWidget*parent = qobject_cast<QWidget*>(box->parent());
if(parent && parent->objectName()!= objectName) // 避免反复生成
{
QWidget* pWidget = new QWidget(parent); //创建一个widget
pWidget->setObjectName(objectName);
QRect rect = box->geometry();
pWidget->setGeometry(rect);
box->setParent(pWidget);//更改父窗口为pWidget
box->move(0,0);
pWidget->setStyleSheet("QWidget{background-color:rgba(225, 225, 225, 255);}");
}
}
//设置字体
QFont font = box->font();
for(auto w:box->findChildren<QWidget*>())
{
w->setFont(font);
}
//下拉列表居中
QStandardItemModel* model = static_cast<QStandardItemModel*>(box->view()->model());
if(model)
{
for(int i = 0; i < model->rowCount(); i ++)
{
if(model->item(i))
model->item(i)->setTextAlignment(Qt::AlignCenter);
}
}
};
显示文本要居中,需要重新设置LineEdit,用setLineEdit设置,样式最好重新设置,否则比较不好看
下拉列表要居中,用QStandardItemModel 去设置,然后遍历每一个下拉项,设置居中
int widthScroll 是下拉框滚动条宽度,也是显示文本左偏移像素
int height是下拉列表子项的高度
这时候,发现点击中间的文字,下拉框不显示,需要点击右侧的向下箭头才显示
如果想要点击下拉框中间文字显示下拉列表,就需要用事件过滤
//下拉框加载事件过滤
void comboBoxInstall(QComboBox* box,QObject*install)
{
if(box)
{
QLineEdit* lineEdit = box->lineEdit();
if(lineEdit)
{
box->installEventFilter(install);
lineEdit->installEventFilter(install);
}
}
};
//下拉框事件过滤,居中,点中显示和隐藏下拉列表
bool comboBoxEventFilter(QObject *target, QEvent *event)
{
static QTime timer =QTime::currentTime();
static QComboBox* curComboBox = 0;//操作的下拉框
if(QString(target->metaObject()->className()) == "QComboBox")
{
QComboBox* box =qobject_cast<QComboBox*>(target);
if (box && event->type() == QEvent::FocusIn)
{
if(box->view()->isVisible())
timer=QTime::currentTime();
curComboBox = box;
}
else if (box && event->type() == QEvent::FocusOut)
{
curComboBox = 0;
}
}
else if(QString(target->metaObject()->className()) == "QLineEdit")
{
if (event->type() == QEvent::MouseButtonPress
|| event->type() == QEvent::MouseButtonDblClick
|| event->type() == QEvent::TouchBegin)
{
QComboBox* box = qobject_cast<QComboBox*>(target->parent());
if(box && box == curComboBox)
{
if(box->isEnabled())
{
int msecs = timer.msecsTo(QTime::currentTime());
if(msecs > 50)
{
box->showPopup();
}
else
{
box->hidePopup();
}
}
}
return true;
}
}
return false;
}
具体到类里使用
comboBoxInstall(box,this);//box要过滤的下拉框
//事件过滤
bool pmAddSample::eventFilter(QObject *target, QEvent *event)
{
if(comboBoxEventFilter(target,event))
{
return true;
}
return QWidget::eventFilter(target, event);
}
使用过程中,发现一个问题,如果是使用 setCurrentText后,首次点击下拉框,不会聚焦到我们设置的选中项,下拉列表选中的是第一项。
发现是使用了setLineEdit 导致,可以再加一个槽
QComboBox::connect(box,&QComboBox::currentTextChanged,[=](const QString &text){
for(int i = 0; i < box->count(); i++)
{
if(box->itemText(i) == text)
{
box->setCurrentIndex(i);
break;
}
}
});