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.