Custom List Implementation
For advanced dropdown lists containing images, text, and interactive elements (similar to QQ login interface), we need to extend QComboBox functionality:
class CustomItemWidget : public QWidget {
Q_OBJECT
signals:
void itemClicked();
void textChanged(const QString &);
public:
CustomItemWidget(const QString &text, QWidget *parent = nullptr);
void updateText(const QString &text);
void setIcons(const QString &normal, const QString &hover);
void setHoverState(bool active);
protected:
bool eventFilter(QObject *, QEvent *) override;
void mousePressEvent(QMouseEvent *) override;
void mouseReleaseEvent(QMouseEvent *) override;
private:
void initUI();
bool m_pressed = false;
QWidget *m_container = nullptr;
QPushButton *m_iconBtn = nullptr;
QLabel *m_textLabel = nullptr;
};
The implementation involves:
- Creating a custom widget with hover effects and click handling
- Managing event filtering for proper hover behavior
- Integrating with QComboBox through QListWidget
void setupCustomList() {
QListWidget *list = new QListWidget;
list->setViewMode(QListView::ListMode);
for (int i = 0; i < 5; i++) {
CustomItemWidget *item = new CustomItemWidget("Item " + QString::number(i));
connect(item, &CustomItemWidget::textChanged, [this, list](const QString &text) {
m_comboBox->hidePopup();
if (m_comboBox->isEditable()) {
m_comboBox->setCurrentText(text);
} else {
for (int j = 0; j < list->count(); ++j) {
if (list->itemWidget(list->item(j)) == sender()) {
m_comboBox->setCurrentIndex(j);
}
}
}
});
item->setIcons(":/icons/normal.png", ":/icons/hover.png");
item->setFixedSize(150, 45);
QListWidgetItem *listItem = new QListWidgetItem(list);
list->setItemWidget(listItem, item);
item->installEventFilter(this);
}
m_comboBox->setModel(list->model());
m_comboBox->setView(list);
m_comboBox->setEditable(true);
m_comboBox->setMaxVisibleItems(3);
}
Custom Table Implementation
For dropdown tables with multiple selectable items, we extend QCheckBox:
class CustomCheckBox : public QCheckBox {
public:
CustomCheckBox(QWidget *parent = nullptr) : QCheckBox(parent) {}
protected:
bool hitButton(const QPoint &) const override { return true; }
};
The table implementation:
void setupCustomTable() {
QTableWidget *table = new QTableWidget(3, 3);
table->verticalHeader()->hide();
table->horizontalHeader()->hide();
table->setShowGrid(false);
for (int row = 0; row < 3; ++row) {
table->setRowHeight(row, 50);
for (int col = 0; col < 3; ++col) {
CustomCheckBox *cb = new CustomCheckBox;
cb->setFixedSize(50, 50);
cb->setText("Option " + QString::number(row*3 + col));
cb->setStyleSheet("QCheckBox {background:lightgray;}"
"QCheckBox:checked {background:white;}");
connect(cb, &QCheckBox::clicked, [this]() {
// Handle multiple selection logic
});
table->setCellWidget(row, col, cb);
cb->installEventFilter(this);
}
}
m_comboBox->setModel(table->model());
m_comboBox->setView(table);
}
Key considerations include proper sizing to avoid scrollbars and handling multiple selections in the dropdown table.