賞金將在 2 天內到期。此問題的答案有資格獲得 100聲望賞金。 Darin Beaudreau希望引起更多人對這個問題的關注。
我正在嘗試解決由我幾年前撰寫的觸摸屏驅動程式引起的 Qt5 應用程式中的問題。問題是我的觸摸屏驅動程式生成滑鼠按下事件來模擬觸摸行為。這是因為在我撰寫它的時候,我的團隊正在使用一個過時的 Linux 作業系統,它沒有原生的觸控驅動程式。
問題是,當我觸摸 /- 按鈕(將滑塊增加/減少一個刻度的滾動按鈕,或者如果按住它會使其快速滾動),滑塊會快速向上/向下滑動,就像我單擊并按住按鈕。這是因為我的驅動程式使用QApplication::postEvent()從單獨的執行緒分派滑鼠事件,并且觸摸和釋放之間的延遲足夠長,以至于它可以注冊單擊并按住型別的事件,盡管釋放事件不會停止滑動。
我會重寫應用程式以使用現在可用的本機觸摸驅動程式,但它沒有提供足夠的控制來執行我的驅動程式所做的事情(我的驅動程式可以生成左、右或中滑鼠事件,而本機驅動程式僅提供左)。
我嘗試重寫要使用的驅動程式QApplication::sendEvent(),但這會導致我無法找出原因的分段錯誤。
那么有沒有辦法可以禁用 QSlider 本身的“單擊并按住”型別的行為?這樣我仍然可以點擊按鈕,但它們一次只會增加/減少一個刻度?
編輯:這是我如何通過驅動程式生成“觸摸”事件的示例。
void InputHandler::touchPress(TouchPoint * tp, QWidget * widget) {
QPoint screenPos(tp->cx(), tp->cy());
QWidget * target = widget;
if(target == NULL) target = QApplication::widgetAt(screenPos);
if(target != NULL) {
QPoint local = target->mapFromGlobal(screenPos);
QMouseEvent * press = new QMouseEvent(QEvent::MouseButtonPress, local, screenPos, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
QApplication::postEvent(target, press);
DBG(" -- touch press on: " << typeid(*widget).name());
// Check to see if the target is a QLineEdit or QComboBox, and if so, set focus on it.
QLineEdit * lineEdit = dynamic_cast<QLineEdit*>(target);
QComboBox * comboBox = dynamic_cast<QComboBox*>(target);
if(lineEdit) lineEdit->setFocus(Qt::MouseFocusReason);
if(comboBox) comboBox->setFocus(Qt::MouseFocusReason);
}
}
EDIT 2: So a coworker played around with the slider and pointed out that he pressed the /- buttons, causing it to slide, and then he clicks the "reset" button we have to reset all controls on the form, the slider would reset and then continue sliding, indicating that the touch press was never released. He then would click the /- buttons normally with the mouse and reset again and it would stop. So even though the logs indicate that the mousePressEvent and mouseReleaseEvent methods are being triggered by my events, they don't seem to have the same behavior as using the mouse.
Any ideas?
EDIT 3: If it helps, I added an eventFilter and printed out every event type that the QSlider receives, from when I first touch the screen to when I release. The events received are:
Mouse Press (2)
Tooltip Change (184)
Paint (12)
Mouse Move (5)
Mouse Move (5)
Mouse Release (3)
But then after the release event, I get spammed in the logs with QEvent::Timer events, which does not happen when I simply click with the mouse, as opposed to touching the slider with the touchscreen. If I then tap somewhere else, drag the slider, or click the slider with the actual mouse, these timer events stop.
Why is my generated QMouseEvent causing these QEvent::Timer events to be generated when I tap the slider with the touchscreen, but not with the mouse?
uj5u.com熱心網友回復:
將一個私有整數變數(比如說 pos)添加到您的 ui 類。轉到滑塊的 sliderPressed 插槽并將其值設定為在 sliderPressed 插槽內
pos = ui->horizontalSlider->value();
然后轉到滑塊的sliderMoved 插槽,并將其值設定為sliderMoved 插槽內的pos 變數的值
ui->horizontalSlider->setValue(pos);
您將看到您只能通過單擊來設定滑塊值,但不能移動它。
uj5u.com熱心網友回復:
生成正確處理的滑鼠按下/釋放事件的最小示例QSlider是:
#include <QApplication>
#include <QMainWindow>
#include <QMouseEvent>
#include <QSlider>
#include <QTimer>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QMainWindow m;
QSlider *slider = new QSlider();
m.setCentralWidget(slider);
m.resize(100, 100);
m.show();
QTimer::singleShot(1000, [&](){
a.postEvent(slider, new QMouseEvent(QEvent::MouseButtonPress, QPoint(50,50), m.mapToGlobal(QPoint(50,50)), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier));
a.postEvent(slider, new QMouseEvent(QEvent::MouseButtonRelease, QPoint(50,50), m.mapToGlobal(QPoint(50,50)), Qt::LeftButton, Qt::NoButton, Qt::NoModifier));
});
return a.exec();
}
此示例在 1 秒后將滑塊值減小 1 個刻度。
請注意,將Qt::NoButton按鈕引數傳遞給QEvent::MouseButtonRelease事件很重要,否則滑塊將繼續移動到當前滑鼠位置(請參閱 參考資料QAbstractSlider::setRepeatAction)。我認為這種行為就是你所說的“按住”。
uj5u.com熱心網友回復:
QSlider 沒有該功能。您可以撰寫一個自定義小部件,當您單擊小部件上的任意位置時,該小部件將手柄放置在單擊位置。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/443307.html
上一篇:使用變換矩陣進行旋轉
