PDA

View Full Version : Pushbutton widget auto Repeat on touchscreen pressed



vegeta1in
28th December 2017, 22:46
Hi,
I have a pushbutton widget on a window and Auto repeat is enabled for that pushbutton.


<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>ManualModes</class>
<widget class="QMainWindow" name="ManualModes">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>272</width>
<height>287</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<property name="styleSheet">
<string notr="true">background-color: rgb(40, 40, 40);</string>
</property>
<widget class="QWidget" name="centralwidget">
<widget class="QPushButton" name="M_Spot_Up">
<property name="geometry">
<rect>
<x>210</x>
<y>2</y>
<width>55</width>
<height>40</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="styleSheet">
<string notr="true">border-image: url(:/resources/resources/other/button_arrow_up_off1.png);</string>
</property>
<property name="text">
<string/>
</property>
<property name="iconSize">
<size>
<width>55</width>
<height>40</height>
</size>
</property>
<property name="autoRepeat">
<bool>true</bool>
</property>
<property name="autoRepeatDelay">
<number>10</number>
</property>
<property name="autoRepeatInterval">
<number>50</number>
</property>
</widget>
</widget>
</widget>
<resources/>
<connections/>
</ui>


Now I have Slots for pressed and released as follows:


void ManualModes::on_M_Spot_Up_pressed()
{
bool res = false;
if(Status.ReadyForMB)
{
qDebug()<<"Spot Up Pressed";
if(this->inAction != true)
{
ui->M_Spot_Up->setStyleSheet(QString::fromUtf8 ("QPushButton {border-image: url(:/resources/resources/other/button_arrow_up_on1.png);}"));
this->inAction = true;
}
res = sendDataPacket(P_BackSpotUp,true);
if(!res)
{
qDebug() << "P_BackSpotUp Packet sent fail";
}
}
}
void ManualModes::on_M_Spot_Up_released()
{
if(Status.ReadyForMB)
{
qDebug()<<"Spot Up Released";
this->inAction = false;
ui->M_Spot_Up->setStyleSheet(QString::fromUtf8 ("QPushButton {border-image: url(:/resources/resources/other/button_arrow_up_off1.png);}"));
}
}


My Intention,Over here Is When I press the button and hold(touchscreen), It should be invoking on_M_Spot_Up_pressed continuously with auto repeat interval. And when I release the button It should invoke on_M_Spot_Up_released.
But In my code, When I press and Hold I am seeing both pressed and released called continuously instead of only pressed.



Debug Output:

Spot Up Pressed
Spot Up Released
Spot Up Pressed
Spot Up Released
Spot Up Pressed
Spot Up Released
Spot Up Pressed
Spot Up Released
Spot Up Pressed
Spot Up Released
Spot Up Pressed
Spot Up Released


Any Help how to resolve this problem on this push button widget.

d_stranz
29th December 2017, 00:07
My guess is that this is how autorepeat is implemented by the driver for your touchscreen - as a sequence of pressed() / released() signals. If you install an event filter on the button and monitor QEvent::MousePress and QEvent::MouseRelease you can see if the touchscreen is actually sending a sequence of these or is emitting the pressed() and released() signals that you are handling.

But except for your code that changes the icon on the pushbutton, having this sequence of signals doesn't change what you want to do with each button press - send a data packet.

I am guessing that your button is also sending a series of clicked() signals that you aren't handling.

A workaround for your problem could be to use a QTimer to change the icon to the inactive state rather than relying on the released() signal: Add a QTimer as a member of your ManualModes class. When the pushbutton pressed() slot is called, change the icon and then start the QTimer with a timeout a bit more than the autorepeat delay. Implement a slot for the QTimer's timeout() signal. In that slot, change the icon back to inactive.

As long as the autorepeat is active, the QTimer will be reset with each pressed() signal and won't fire because its timeout delay is longer than the autorepeat delay. When you release the button, the timer will timeout shortly afterward and the icon will be reset.

vegeta1in
29th December 2017, 00:28
Hi @d_stranz,
Thanks for your reply. Seems the QTimer workaround might work for us to change the image to inactive. But what we see is some times onpress also, we are seeing pressevent(on_M_Spot_Up_pressed) not being invoked. In those cases, if we swipe little bit then the press event is invoked. So to be more precise, This scenario looks similar to problem mentioned in the post: https://stackoverflow.com/questions/26424333/problems-catching-tap-and-hold-touch-event-on-qpushbutton-in-qt
But in our case it's embedded application with only touch input. So will TapAndHoldGesture be helpful to us? If so can you please point us to some examples on how to do this?

d_stranz
29th December 2017, 17:02
So will TapAndHoldGesture be helpful to us?

I can't really help you there. I haven't done any programming for touchscreen gesture applications - everything I have done so far is for desktop / laptop use with the keyboard and mouse. If I ever start in on that, I am sure I will run into the same walls as you have.