现象:
在主界面MainWindow界面中存在QCombobox和QPushButton。当使用鼠标或者触控点击QComboBox时会出现下拉列表。
1.使用鼠标点击QPushButton,会正常产生click事件消息,同时响应其槽函数,于此同时QComboBox的下拉列表会隐藏;
2.使用触控点击QPushButton,只产生QPushButton的Press状态的QSS效果,就变成异常,也并不会产生Click事件,但同时QComboBox的下拉列表会隐藏。
分析:
通过qapplication打印以上操作的MouseEvent和TouchEvent事件,发现触控屏操作的事件发生过程如下:
QPushButton响应的Press事件在QComboBox下拉列表hideEvent之后。
因此,
提出两个方案解决以上异常问题:
1.修改QPushButton的QSS效果为Release状态,但是对于有按下效果如长按的按钮就会不符合要求,同时鼠标和触控的操作也会不一致;
2.将QPushButton在此类情况下的Press事件拦截,即在出现了QComboBox下拉列表时,将Qapplicaiton的静态标志Flag=true;当下一个产生MouseButtonPress事件时,对点击事件出现异常的按钮或者其他控件进行过滤,设置Flag=false,返回True,就可以阻止鼠标操作产生点击事件,和触控操作保持一致。其关键代码如下:
QApplication中处理:
bool application::notify(QObject * obj, QEvent *event)
{
switch (event->type())
{
case QEvent::MouseButtonPress:
{
//qDebug() << "application:" << obj->metaObject()->className() << ",press event type" << event->type();
const char*objClassName = obj->metaObject()->className();
if (objClassName == QStringLiteral("UIPushButton")||
objClassName == QStringLiteral("QPushButton")||
objClassName == QStringLiteral("RunDesCriptionButton")||
objClassName == QStringLiteral("QLabel"))
{
if (m_comboBoxPopup)
{
m_comboBoxPopup = false;
return true;
}
}
}
。。。。。。。。
}
QComboBox下的处理:下拉列表弹出后将标记Flag设置为True,其他情况都不需要进行过滤
bool UIComboBoxEx::eventFilter(QObject *target, QEvent *event)
{
if(target == view()->viewport())
{
if(event->type() == QEvent::MouseButtonPress) {
qDebug() << "viewport QEvent::MouseButtonPress";
viewOnMousePress(static_cast<QMouseEvent *>(event));
return true;
} else if(event->type() == QEvent::MouseButtonRelease) {
qDebug() << "viewport QEvent::MouseButtonRelease";
viewOnMouseRelease(static_cast<QMouseEvent *>(event));
return true;
} else if(event->type() == QEvent::MouseMove) {
qDebug() << "viewport QEvent::MouseMove";
viewOnMouseMove(static_cast<QMouseEvent *>(event));
return true;
} else if (event->type() == QEvent::Show) {
application::m_comboBoxPopup = true;
}
}
return QComboBox::eventFilter(target, event);
}