KeyPress Event waits for MousePress Event qt - qt

So I'm writing a qtwidget that requires keyboard and mouse input by overriding the respective functions. However the keypress event doesnt happen until a mousepress event occurs. I've played around with the focus a bit and that doesnt seem to help. I feel like I'm missing something regarding how qt processes events. Can any of you fill me in. Thank you
Here are what i think are the relevant bits of code. Let me know if you need more
MeshTest::MeshTest(QWidget *parent) :
QGLWidget(parent)
{
setFocusPolicy(Qt::StrongFocus);
/* Other stuff */
}
void MeshTest::mousePressEvent(QMouseEvent *event)
{
if (event->button() == Qt::LeftButton) {
/* Some math/ray casting here */
hasHit = MeshTest::findIntersections(x,y,z,dirx,diry,dirz);
}
}
void MeshTest::mouseReleaseEvent(QMouseEvent *event){
if (event->button() == Qt::LeftButton) {
/* Some ray casting stuff here */
}
if(hasHit)
updateGL();
}
void MeshTest::keyPressEvent(QKeyEvent* event){
printf("Key Pressed\n"); //Just for debugging this particular bug
}

Okay so i fixed this a few days ago. The solution is to overide QWidget::event(QEvent *event)
and do all event handling in the function itself

Related

Is there any way to disable keyPressEvent temporarily?

I reimplement keyPressEvent function in my widget.
I want to disable key press while doing some works in keyPressEvent function like this:
void TrackingForm::keyPressEvent(QKeyEvent *event)
{
// disable get keyPress
doWork();
// enable
}
the other way is clear buffer of events posted (queueded events). I use QApplication::removePostedEvents in keyPressEvent function but it does not work:
void TrackingForm::keyPressEvent(QKeyEvent *event)
{
doWork(); // this function takes about 3 seconds
QApplication::removePostedEvents(this);
}
Can someone help me?
thanks a lot
You could try to execute doWork() in a separate thread - then you could just ignore events in keyPressEvent() while doWork() is running...
For example you could try this:
void TrackingForm::keyPressEvent(QKeyEvent *event)
{
if (!workInProgress) //workInProgress is a bool member
QtConcurrent::run(doWork);
//doWork() sets workInProgress to true before work,
//and to false after work is done
else
event->ignore();
}

Qt mousemoveevent + Qt::LeftButton

Quick question, why does:
void roiwindow::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
QGraphicsScene::mouseMoveEvent(event);
qDebug() << event->button();
}
return 0 instead of 1 when I'm holding down the left mouse button while moving the cursor around in a graphicscene. Is there anyway to get this to return 1 so I can tell when a user is dragging the mouse across the graphicscene. Thanks.
Though Spyke's answer is correct, you can just use buttons() (docs). button() returns the mouse button that caused the event, which is why it returns Qt::NoButton; but buttons() returns the buttons held down when the event was fired, which is what you're after.
You can know if the left button was pressed by looking at the buttons property:
if ( e->buttons() & Qt::LeftButton )
{
// left button is held down while moving
}
Hope that helped!
The returned value is always Qt::NoButton for mouse move events. You can use Event filter to solve this.
Try this
bool MainWindow::eventFilter(QObject *object, QEvent *e)
{
if (e->type() == QEvent::MouseButtonPress && QApplication::mouseButtons()==Qt::LeftButton)
{
leftbuttonpressedflag=true;
}
if (e->type() == QEvent::MouseMove)
{
QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(e);
if(leftbuttonpressedflag && mouseEvent->pos()==Inside_Graphics_Scene)
qDebug("MouseDrag On GraphicsScene");
}
return false;
}
And also don't forget to install this event filter in mainwindow.
qApplicationobject->installEventFilter(this);

Qt: How to filter accidental (consecutive) MouseButtonRelease and MouseButtonPress events?

My problem is a poor resistive touch screen. When you drag your finger across the screen. The drag randomly cuts off because of the MouseButtonRelease event.
I would like to fix this by filtering the mouseEvents and removing all consecutive MouseButtonRelease and MouseButtonPress events if they occured e.g. less than 100ms appart. I would like to do this application-wide.
I already tried an eventFilter but it doesn't work properly. The stored MouseButtonRelease-events don't get sent to right objects. I installed this by installEventFilter(new MouseFilter(this)); at a widget, but all the mouse releases get lost.
Do you suggest a different approach or is there something wrong with my code?
#include "mousefilter.h"
#include <QApplication>
#include <QEvent>
#include <QMouseEvent>
#include <QTimer>
MouseFilter::MouseFilter(QObject *parent) :
QObject(parent),
storedEvent_(0)
{
}
void MouseFilter::send() {
if ( storedEvent_ == 0 ) {
return;
}
QApplication::sendEvent(parent(), storedEvent_);
delete storedEvent_;
storedEvent_ = 0;
}
bool MouseFilter::eventFilter(QObject *object, QEvent *event) {
if ( event->type() == QEvent::MouseButtonRelease ) {
QMouseEvent* release = static_cast<QMouseEvent*>(event);
// Dalay the event
storedEvent_ = new QMouseEvent(QEvent::MouseButtonRelease, release->pos(), release->globalPos(),
release->button(), release->buttons(), release->modifiers());
QTimer::singleShot(100, this, SLOT(send()));
return true;
}
else if ( storedEvent_ != 0 && event->type() == QEvent::MouseButtonPress ) {
// Clear stored release and ignore new press.
delete storedEvent_;
storedEvent_ = 0;
return true;
}
return QObject::eventFilter(object, event);
}
You are in a world of pain, been there. I complained to the hardware people and got nowhere.
An approach could be to do all the release events yourself. Basically whilst the finger is in contact you get an event (even if its stationary). Therefore based on that logic you can start a timer, then after 100ms of no touch events you fire off the mouse release.
The way that the QTimer works is that you can repeatedly call .start() and it will restart the count down.
Of course this is filled with problems in that its dependant on a magic number of 100ms, it reduces the responsiveness of your application and only fixes the bug in your application not system wide as it should be.

Qt 4.4: disabled widgets receiving mouse events

As the title suggests, is there a way for a disabled widget to receive mouse events?
I'm using QWidget::setEnabled() for changing the appearance of widgets but I still want to receive their mouse events. Thanks in advance :)
You can do this with an event filter on the widget in question. See QObject::eventFilter(). Your implementation might look something like this:
bool MainWindow::eventFilter(QObject *obj, QEvent *event)
{
if (ui->pushButton)
{
if (event->type() == QEvent::MouseButtonRelease)
{
qDebug() << "mouse button";
return true;
} else
{
return false;
}
} else
{
// pass the event on to the parent class
return QMainWindow::eventFilter(obj, event);
}
}
This will work even if the button is disabled.

Set consistent mouse cursor for QWidget

I have sub-classed QWidget to draw on it using mouse.
I use setCursor to change its cursor to cross shape.
It is working fine but as soon as I press the mouse button on it (for example to draw freehand line), the cursor changes back to application cursor.
Note that I do not want to use setOverrideCursor on mouseenter event for example because I want to change cursor only for this widget and not for entire application, and I have a better workaround (as follows) anyways.
My current solution is to use
setCursor(cursor());
in my overridden mousePressEvent(QMouseEvent * event) and mouseDoubleClickEvent(QMouseEvent * event)
The latter is because for some reason double click also changes the cursor to the application cursor for a moment!
The workaround works :) but I would like to see if there is any better solution, that asks QT not to change the cursor at all.
I should add that drag/drop is not activated.
Here is some source code snippet as requested:
class MyWidget : public QWidget
{
void paintEvent( QPaintEvent * /*event*/ );
void resizeEvent( QResizeEvent * event );
void mouseDoubleClickEvent ( QMouseEvent * event );
void mousePressEvent( QMouseEvent* event );
void mouseReleaseEvent( QMouseEvent* event );
void mouseMoveEvent( QMouseEvent* event );
void wheelEvent( QWheelEvent* event );
}
Then I override the following (for the workaround)
void MyWidget::mouseDoubleClickEvent(QMouseEvent * event)
{
// ... do some other stuff ...
// This is a workaround to prevent the cursor from changing
setCursor(cursor());
event->accept();
}
void MyWidget::mousePressEvent(QMouseEvent * event)
{
// ... do some other stuff ...
// This is a workaround to prevent the cursor from changing
setCursor(cursor());
event->accept();
}
To change cursor assuming that mywidget is instantiated with my class, I do this: mywidget->setCursor(Qt::CrossCursor)
Again, it changes the cursor as expected when I hover over my control, but it changes back to the application cursor once I press the mouse button (thus the need for the above workaround)
QApplication.setOverrideCursor(QtGui.QCursor(Qt.CrossCursor))
and when the QWidget closed, set back to the original cursor
Ok I still have not found any answer for this, so here is the workaround:
void MyWidget::mouseDoubleClickEvent(QMouseEvent * event)
{
// ... do some other stuff ...
// This is a workaround to prevent the cursor from changing
setCursor(cursor());
event->accept();
}
void MyWidget::mousePressEvent(QMouseEvent * event)
{
// ... do some other stuff ...
// This is a workaround to prevent the cursor from changing
setCursor(cursor());
event->accept();
}

Resources