How to override QApplication::notify in Qt
Asked Answered
M

3

16

I am trying to handle exception in my Qt application, I went through a couple of posts which indicated of overriding the QApplication::notify method to handle exceptions in a efficient way in Qt. I am not sure where should I add this overriden method. Is it the mainwindow.h or main.cpp? I added the following function in my MainWindow.h:

bool
notify(QObject * rec, QEvent * ev)
{
  try
  {
    return QApplication::notify(rec,ev);
  }
  catch(Tango::DevFailed & e)
  {
    QMessageBox::warning(0,
                         "error",
                         "error");
  }

  return false;
}

When I build my project I get the following error:

error: cannot call member function 'virtual bool QApplication::notify(QObject*, QEvent*)' without object

I am new to c++ and Qt.Could you let me know how I could implement this so that all my exceptions would be handled in an efficient way and the application does not crash.

Myrtismyrtle answered 22/12, 2014 at 17:49 Comment(11)
@lpapp I have not deselected the answer. I tried using yours too and it worked.But apparently it allows me to select only one post as the answer.Myrtismyrtle
@lpapp So I am trying to write values to a device through my form. The fields contain the original values which are being read. Now when the user is trying to write values I want to make sure that proper data is entered. If there are any errors they are handled by Tango(api used to write and read values from the device) and printed on the output window and then the application crashes. So I wanted to shown some meaningful message as writing on the output window is not helpful.So used a try catch block around the update function. Now it shows the message box and then application crashes.Myrtismyrtle
Which OS, compiler and Qt versions exactly are you using out of curiosity?Behoove
@lpapp I am using Qt5.. Not sure where to check the compiler? But to run the program i just follow these steps run qmake>>Build>>Run.Myrtismyrtle
@lpapp using it on debian..Myrtismyrtle
@lpapp I edited my post and added the main.cpp and updatescreen.cpp to give you a better picture of what I am trying to do.Myrtismyrtle
@lpapp I first used your code and then some minor modifications which worked. Then I used anouther solution. I have posted the code that I used.Myrtismyrtle
@lpapp I am using the new compiler. I have this in my .pro file of the project QMAKE_CXXFLAGS += -std=c++11 which actually means that I am using the c++11 compiler, thats the reason I accepted the solution.Myrtismyrtle
QMAKE_CXXFLAGS += -std=c++11 is not the recommended use... Either way, you said you used my solution with modification, yet you chose to accept another solution without having any problem with my solution and then you ask for my help. You should accept a solution that works. You accepted an answer, so your problem is solved. Why are you asking me then??Behoove
@lpapp I did say that your solution is working. Then I got another problem even after implementing it. Thats when I posted the question. Anyways thanks for your help.Myrtismyrtle
Maybe you will be careful next time when you withdraw a selection!Behoove
C
15

This is a method of a QApplication object. In order to override the notify method you must inherit from QApplication and in your main() you should instantiate a class as the Qt Application

#include <QApplication>
class Application final : public QApplication {
public:
    Application(int& argc, char** argv) : QApplication(argc, argv) {}
    virtual bool notify(QObject *receiver, QEvent *e) override {
         // your code here
    }
};

int main(int argc, char* argv) {
    Application app(argc, argv);
    // Your initialization code
    return app.exec();
}
Costin answered 22/12, 2014 at 17:55 Comment(8)
So when I catch an exception in my code should i call the notify function? As of now I have an update function inside a try catch block and when it fails the exception is raised and application crashes.So I am not sure why it is crashing.Myrtismyrtle
In the application that I develop at work we do exactly the same exception handling. Picture this, the notify method is called inside a loop for almost every Qt event. If you catch an exception and return false Qt is going to keep its loop running and your app will not crash. The only reason why this works is because Qt has its own event loop and you can intercept each event inside this notifyCostin
I added the same code into my Qt Application. Should that method be called again in the updatescreen.cpp shown above.Could you let me know what I am missing here.I edited my question and included the code that I am using in my application.Myrtismyrtle
I don't think so reading your description. The notify is called automatically for you. It is part of Qt event loop.Costin
Do you know if its crashing due an exception or due a signal? They are different things. It is crashing due to SIGSEGV for instance? If so you're have to handle it correctly. Correct signal handling is complicated and I am going to sugest the E4C library that we use in our work. code.google.com/p/exceptions4c. Create an E4C context in your notify method in order to check for any signal exception.Costin
Let us continue this discussion in chat.Myrtismyrtle
I am not using any signals It is just a basic update method...in that method I have a write method...if that write method fails then the exception should be raised...the exception is being handled...but the application crashes...Myrtismyrtle
There is a "public:" missing to make the constructor public.Narcolepsy
G
4

error: cannot call member function 'virtual bool QApplication::notify(QObject*, QEvent*)' without object

That error message is trying to write that you are trying to call a non-static method without an actual object. Only static methods could work like that. Even if it was intended like that, which it is not, it could not be a static method anyway as C++ does not support virtual static methods (sadly, but that is another topic).

Therefore, I would personally do something like this:

main.cpp

#include <QApplication>
#include <QEvent>
#include <QDebug>

class MyApplication Q_DECL_FINAL : public QApplication
{
    Q_OBJECT
public:
    MyApplication(int &argc, char **argv) : QApplication(argc, argv) {}

    bool notify(QObject* receiver, QEvent* event) Q_DECL_OVERRIDE
    {
        try {
            return QApplication::notify(receiver, event);
        //} catch (Tango::DevFailed &e) {
            // Handle the desired exception type
        } catch (...) {
            // Handle the rest
        }        

         return false;
     }
};

#include "main.moc"

int main(int argc, char **argv)
{
    MyApplication application(argc, argv);
    qDebug() << "QApplication::notify example running...";
    return application.exec();
}

main.pro

TEMPLATE = app
TARGET = main
QT += widgets
SOURCES += main.cpp

Build and Run

qmake && make && ./main
Goodden answered 22/12, 2014 at 18:2 Comment(0)
A
1

Just like with other event handlers in Qt, you need to define a child class derived from QApplication and implement bool notify (QObject *receiver, QEvent *e) there, then use your class instead of QApplication.

Anthracoid answered 22/12, 2014 at 17:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.