Re-implemented QComboBox and QLineEdit, the dropdown flash with a left-click using the touchpad
-
I have designed a custom QComboBox and re-implemented the QLineEdit and dropdown content display. When I use a mouse click, everything displays correctly, but when I use the keyboard touchpad to left-click, the dropdown briefly appears and then disappears. I suspect it's an issue with the touchpad signal, but the code doesn't enter the QTouchEvent, so it's not an issue with the touchpad signal. The problem is that when I left-click using the touchpad, the dropdown flashes briefly and disappears. What I want to achieve is for the left-click behavior from the touchpad to be the same as that of the mouse left-click.
The full code is shown below:
#include "SShapeComboBox.h" #include <QLayout> #include <QStandardItemModel> #include <QPainter> #include <QApplication> #include <QAbstractItemView> namespace CustomUILib { CustomUILib::SShapeComboBox::SShapeComboBox(QWidget *parent) : QComboBox(parent) { Init(); } CustomUILib::SShapeComboBox::~SShapeComboBox() {} void SShapeComboBox::paintEvent(QPaintEvent *event) { QComboBox::paintEvent(event); } QSize SShapeComboBox::sizeHint() const { QSize size = QComboBox::sizeHint(); size.setWidth(size.width() * 2); return size; } void SShapeComboBox::Init() { qApp->setAttribute(Qt::AA_SynthesizeMouseForUnhandledTouchEvents, false); qApp->setAttribute(Qt::AA_SynthesizeTouchForUnhandledMouseEvents, true); this->setAttribute(Qt::WA_AcceptTouchEvents, true); this->_lineEdit = new ShapeLineEdit("", "", this); this->setLineEdit(static_cast<QLineEdit *>(this->_lineEdit)); connect(this, QOverload<int>::of(&QComboBox::activated), this, [&](int index) { this->clearEditText(); if (index >= 0) { QString firstLabel = this->itemText(index); QString secondLabel = this->itemData(index, Qt::UserRole).toString(); this->_lineEdit->SetLabelTexts(firstLabel, secondLabel); } else { this->_lineEdit->ClearLabel(); } }); this->setItemDelegate(new ComboBoxShapeDelegate(this)); } void SShapeComboBox::Reset() { this->_lineEdit->ClearLabel(); QComboBox::clear(); } QString SShapeComboBox::GetCurrentText() const { return this->itemText(this->currentIndex()); } ShapeLineEdit::ShapeLineEdit(const QString firstLabel, const QString secondLabel, QWidget *parent) : QLineEdit(parent) { this->setAttribute(Qt::WA_AcceptTouchEvents, true); this->setReadOnly(true); QHBoxLayout *layout = new QHBoxLayout(this); layout->setContentsMargins(0, 0, 0, 0); _label1 = new QLabel(firstLabel, this); _label2 = new QLabel(secondLabel, this); layout->addWidget(_label1); layout->addStretch(); layout->addWidget(_label2); this->setLayout(layout); } void ShapeLineEdit::SetLabelTexts(QString firstLabel, QString secondLabel) { _label1->setText(firstLabel); _label2->setText(secondLabel); } void ShapeLineEdit::ClearLabel() { _label1->setText(""); _label2->setText(""); } void ShapeLineEdit::mouseReleaseEvent(QMouseEvent *event) { return QLineEdit::mouseReleaseEvent(event); } void ShapeLineEdit::mousePressEvent(QMouseEvent *event) { if (event->type() == QEvent::TouchBegin) { int i = 1; } else { if (event->button() == Qt::LeftButton) { QComboBox *comboBox = qobject_cast<QComboBox *>(parentWidget()); if (comboBox) { bool noMatched = false; if (comboBox->count() == 0) { QStandardItemModel *model = qobject_cast<QStandardItemModel *>( comboBox->model()); if (model) { QStandardItem *item = new QStandardItem(tr("No matches found")); item->setFlags(item->flags() & ~Qt::ItemIsEnabled); model->appendRow(item); } comboBox->clearEditText(); comboBox->setCurrentIndex(-1); ClearLabel(); } comboBox->showPopup(); } } } QLineEdit::mousePressEvent(event); } void ShapeLineEdit::keyPressEvent(QKeyEvent *event) { return; if (event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter || event->key()== Qt::Key_Escape) { return; } QLineEdit::keyPressEvent(event); } bool SShapeComboBox::event(QEvent *event) { if (event->type() == QEvent::TouchBegin || event->type() == QEvent::TouchUpdate || event->type() == QEvent::TouchEnd) { QTouchEvent *touchEvent = static_cast<QTouchEvent *>(event); return true; } return QWidget::event(event); } ComboBoxShapeDelegate::ComboBoxShapeDelegate(QObject *parent) : QStyledItemDelegate(parent) { } void ComboBoxShapeDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { painter->save(); QString firstLabel = index.data(Qt::DisplayRole).toString(); QString secondLabel = index.data(Qt::UserRole).toString(); QStyleOptionViewItem opt = option; initStyleOption(&opt, index); if (opt.state & QStyle::State_Selected) { painter->setBrush( QColor(68, 140, 242, 77)); // rgba(68, 140, 242, 0.3) painter->setPen(Qt::NoPen); painter->drawRect(opt.rect); } else { QApplication::style()->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, painter, opt.widget); } painter->setFont(option.font); painter->setPen(option.palette.color(QPalette::Text)); QRect firstLabelRect = option.rect; firstLabelRect.setLeft(option.rect.left() + 10); firstLabelRect.setRight(option.rect.left() + (option.rect.width() / 2)); QRect secondLabelRect = option.rect; secondLabelRect.setLeft(option.rect.left() + (option.rect.width() / 2)); secondLabelRect.setRight(option.rect.right() - 10); painter->drawText(firstLabelRect, Qt::AlignLeft | Qt::AlignVCenter, firstLabel); painter->drawText(secondLabelRect, Qt::AlignRight | Qt::AlignVCenter, secondLabel); painter->restore(); } QSize ComboBoxShapeDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const { QSize size = QStyledItemDelegate::sizeHint(option, index); size.setWidth(size.width() * 2); return size; } }
Please Help!
-
Maybe your touchpad is broken ? I think it just performs a mouse click action when you "left-click" touchpad, so it will send mouse press event. You can reload the
event
function, print all events, and then after you left-clicked on the trackpad, look at what events are triggered. -
@Gaobo My trackpad is on my laptop and is working fine. From the information on the Internet, it seems that it is indeed converted from the trackpad to the mouse click event, and it can indeed enter the mouse click event, but the drop-down box will flash and disappear after the left mouse button event is executed.
-
@Gaobo said in Re-implemented QComboBox and QLineEdit, the dropdown flash with a left-click using the touchpad:
Does ‘left mouse button’ mean pressing the left button of the touchpad or just touching it once with a single finger?
Just touch it once with a single finger.
@Gaobo said in Re-implemented QComboBox and QLineEdit, the dropdown flash with a left-click using the touchpad:
Is that question also appear on qt original QComboBox?
The question does not appear on qt original QComboBox.
CustomComboBox initialize like:
auto items = _treeModel->GetItemList(); for (int i = 0; i < items.size(); ++i) { auto name = items[i][0]->text(); auto shape = items[i][1]->text(); ui.comboInput->addItem(name, shape); }
The full code is in my question, so you can try it out if it's convenient for you