需求
点击QComboBox时,下拉列表以多行多列的表格展示出来。
实现
直接上代码:
#include <QComboBox>
#include <QTableWidget>
#include <QVBoxLayout>
#include <QWidget>
#include <QEvent>
#include <QMouseEvent>
#include <QLineEdit>
class ComboBoxWithTableWidget : public QComboBox {
Q_OBJECT
public:
ComboBoxWithTableWidget(QWidget *parent = nullptr) : QComboBox(parent) {
// 隐藏默认的下拉箭头
setEditable(true);
lineEdit()->setReadOnly(true);
// 创建一个隐藏的容器来存放我们的表格
popupWidget = new QWidget(this);
popupWidget->setWindowFlags(Qt::Popup | Qt::FramelessWindowHint);
QVBoxLayout *layout = new QVBoxLayout(popupWidget);
layout->setContentsMargins(0, 0, 0, 0);
layout->setSpacing(0);
tableWidget = new QTableWidget(5, 2, popupWidget); // 5行2列
for (int row = 0; row < 5; ++row)
{
for (int col = 0; col < 2; ++col)
{
QTableWidgetItem *item = new QTableWidgetItem(QString("Item %1%2").arg(row).arg(col));
tableWidget->setItem(row, col, item);
}
}
tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
tableWidget->setSelectionMode(QAbstractItemView::SingleSelection);
layout->addWidget(tableWidget);
popupWidget->resize(220,200);
connect(tableWidget, &QTableWidget::cellClicked, this, &ComboBoxWithTableWidget::onCellClicked);
popupWidget->hide();
}
protected:
void showPopup() override
{
if (popupWidget->isHidden())
{
QComboBox::showPopup();
//popupWidget->resize(this->width(), tableWidget->height() + 2); //(可能需要调整)
popupWidget->move(this->mapToGlobal(QPoint(0, this->height())));
popupWidget->show();
tableWidget->setFocus();
}
}
void hidePopup() override
{
if (popupWidget->isVisible())
{
popupWidget->hide();
QComboBox::hidePopup();
}
}
private slots:
void onCellClicked(int row, int column)
{
QString text = tableWidget->item(row, column)->text();
this->setCurrentText(text);
hidePopup(); // 选择后隐藏下拉列表
}
private:
QWidget *popupWidget = nullptr;
QTableWidget *tableWidget= nullptr;
};