event(QEvent*) conflicts with mousePressEvent(QMouseEvent *)? - qt

In QT: I use a class inherited from QToolButton and rewrite event(QEvent*), now I want to add 'mousePressEvent', but it never gets hit, does event(QEvent*) conflict with mousePressEvent(QMouseEvent *) ? Thank you.
bool IconLabel::event (QEvent* e ) {
if ( e->type() == QEvent::Paint) {
return QToolButton::event(e);
}
return true;
}
void IconLabel::mousePressEvent(QMouseEvent* e)
{
int a = 1;//example
a = 2;// example//Handle the event
}
The class is:
class IconLabel : public QToolButton
{
Q_OBJECT
public:
explicit IconLabel(QWidget *parent = 0);
bool event (QEvent* e );
void mousePressEvent(QMouseEvent* e);
signals:
public slots:
};

All events received by a widget pass through event(..), and then are redirected to the appropriate event handler method. You have made the mistake of not forwarding on any events except paint events, if you just want to add mouse press event handling do this:
bool IconLabel::event (QEvent* e ) {
if ( e->type() == QEvent::Paint ||
e->type() == QEvent::QEvent::MouseButtonPress ) {
return QToolButton::event(e);
}
return true;
}
Also event handler methods should really be in protected, because events are only supposed to be distributed via the event queue (QCoreApplication::postEvent(..), etc.).

Related

How to catch QEvent::LanguageChange in QObject

My goal is to retranslate a QObject subclass on the fly.
In QWidget it's really simple to catch QEvent::LanguageChange: we just override changeEvent. However, there is not such method in QObject and this is where I'm stuck.
How to catch QEvent::LanguageChange in QObject?
You can simply override the QObject::event method...
class my_object: public QObject {
using super = QObject;
protected:
virtual bool event (QEvent *event) override
{
if (event->type() == QEvent::LanguageChange) {
/*
* Retranslation code goes here...
*/
/*
* Return true to prevent further processing. This may
* or may not be what you want depending on your needs.
*/
return true;
}
/*
* Fall through to the base class implementation.
*/
return super::event(event);
}
};
Alternatively, you could put the same logic in an event filter and attach that to the QObject of interest.

How to connect clicking on context help button with my custom action?

I have a dialog with two buttons in the title bar: the context help button and the close button. How can I find out that the user clicked the context help button to perform my custom action? (I want to show some help page in the browser as in VS dialogs.)
I found a similar question, but how to do this with qt?
Context help button behaviour on CPropertySheet
Update.
Now I use the code like this:
class MyHelper : public QObject
{
Q_OBJECT
public:
explicit MyHelper( QObject * parent = nullptr ) {
qApp->installEventFilter( this );
}
protected:
virtual bool eventFilter( QObject * obj, QEvent * ev ) override {
if ( ev->type() == QEvent::EnterWhatsThisMode ) {
showHelp( QApplication::activeWindow() );
return true;
}
return QObject::eventFilter( obj, ev );
}
private:
void showHelp( QWidget * sender ) {
//TODO
}
};
I believe that QWidget::nativeEvent is what you are looking for.

QQuickPaintedItem mouseReleaseEvent gets only called after doubleclick

I've derived a class from QQuickPaintedItem in which I want to handle the mousePressEvent and the mouseReleasEvent (and also the mouseMoveEvent but that is not my prolem now).
The mousePressEvent gets called properly everytime the left mouse button is pressed. But the mouseReleaseEvent gets only called after a double click. What I expected is to get the event everytime the button is released. How can I change this?
This is what I do:
MyView::MyView(QQuickItem *parent):
QQuickPaintedItem(parent)
{
setAcceptedMouseButtons(Qt::LeftButton);
}
void MyView::mousePressEvent(QMouseEvent *evt)
{
//gets called after every single mouse click
qDebug("mousePressEvent");
if(evt->button() == Qt::LeftButton)
{
//do something...
evt->accept();
}
else
{
evt->ignore();
}
QQuickPaintedItem::mousePressEvent(evt);
}
void MyView::mouseReleaseEvent(QMouseEvent *evt)
{
//gets only called when releasing the mouse button after a double click
qDebug("mouseReleaseEvent");
if(evt->button() == Qt::LeftButton)
{
//do something...
evt->accept();
}
else
{
evt->ignore();
}
QQuickPaintedItem::mouseReleaseEvent(evt);
}
So I finally found the solution!
Calling the base class implementation is a bad idea since the base class simply calls ignore() on the event. Here is the base class implementation:
void QWindow::mousePressEvent(QMouseEvent *ev)
{
ev->ignore();
}
void QWindow::mouseReleaseEvent(QMouseEvent *ev)
{
ev->ignore();
}
So this is how it works:
MyView::MyView(QQuickItem *parent):
QQuickPaintedItem(parent)
{
setAcceptedMouseButtons(Qt::LeftButton);
}
void MyView::mousePressEvent(QMouseEvent *evt)
{
//gets called after every single mouse click
qDebug("mousePressEvent");
if(evt->button() == Qt::LeftButton)
{
//do something...
evt->accept();
}
else
{
evt->ignore();
}
//DON'T DO THIS:
//QQuickPaintedItem::mousePressEvent(evt);
}
void MyView::mouseReleaseEvent(QMouseEvent *evt)
{
//now gets called with every mouse release since we don't call the base class any more
qDebug("mouseReleaseEvent");
if(evt->button() == Qt::LeftButton)
{
//do something...
evt->accept();
}
else
{
evt->ignore();
}
//DON'T DO THIS:
//QQuickPaintedItem::mouseReleaseEvent(evt);
}

Make QLineEdit detect Tab Key Press event?

I couldn't find anything in the docs. I found one solution that uses PyQt or something, but I'd rather not have to use that. Also, it would be pretty nice if there was a signal for it, but it doesn't look like there is.
1.When you install an event filter as Sam suggested (m_lineEdit->installEventFilter(this);) you need to handle QEvent::KeyPress and check the key to be equal Qt::Key_Tab:
bool MainWindow::eventFilter(QObject *obj, QEvent *event)
{
if (obj == m_lineEdit) {
if (event->type() == QEvent::KeyPress) {
QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
if (keyEvent->key() == Qt::Key_Tab)
{
//do what you need;
return true;
}
}
// pass the event on to the parent class
return QMainWindow::eventFilter(obj, event);
}
2.Another way to do that is to create a new class inherited from QLineEdit and reimplement keyPressEvent:
void LineEdit::keyPressEvent(QKeyEvent* event)
{
if (keyEvent->key() == Qt::Key_Tab)
{
emit tabPressed();
return;
}
QLineEdit::keyPressEvent(event);
}
You should be able to use QObject::installEventFilter(QObject*) to intercept the key press event. There's an example here: http://qt-project.org/doc/qt-4.8/qobject.html#installEventFilter .

Qt: QMouseEvent - How to get widget

I am using QMouseEvent and QKeyEvents in my program. I programmatically make various widgets (QDockWidgets and QCustomPlots).
I would like to use a single click and keypress handler function. However, I am struggling to get the widget that is actually being clicked, so that I can do certain stuff within that widget.
Is there a way to return from a ClickEvent the name of the widget that was clicked?
You can implement eventFilter in your mainWindow and listen for events from widgets there :
bool MainWindow::eventFilter(QObject * obj, QEvent * event)
{
if((myWidget *)obj == widget1 && event->type()==QEvent::KeyPress)
{
int pressedKey = ((QKeyEvent*)event)->key();
...
}
else if((myWidget *)obj == widget2 && event->type()==QEvent::MouseButtonRelease)
{
if(((QMouseEvent*)event)->button() == Qt::LeftButton)
{
...
}
}
return false;
}
Also do not forget to install event filters for your widgets in the mainWindow constructor :
widget1->installEventFilter(this);
widget2->installEventFilter(this);

Resources