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.

László Papp
  • 51,870
  • 39
  • 111
  • 135
Valla
  • 2,414
  • 11
  • 42
  • 73
  • @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. – Valla Dec 22 '14 at 19:06
  • @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. – Valla Dec 22 '14 at 19:28
  • Which OS, compiler and Qt versions exactly are you using out of curiosity? – László Papp Dec 22 '14 at 19:29
  • @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. – Valla Dec 22 '14 at 19:31
  • @lpapp using it on debian.. – Valla Dec 22 '14 at 19:38
  • @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. – Valla Dec 22 '14 at 19:47
  • @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. – Valla Dec 23 '14 at 04:22
  • @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. – Valla Dec 23 '14 at 04:33
  • `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?? – László Papp Dec 23 '14 at 04:35
  • @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. – Valla Dec 23 '14 at 05:14
  • Maybe you will be careful next time when you withdraw a selection! – László Papp Dec 26 '14 at 18:40

3 Answers3

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();
}
McLeary
  • 1,231
  • 2
  • 13
  • 21
  • 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. – Valla Dec 22 '14 at 19:05
  • 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 notify – McLeary Dec 22 '14 at 20:45
  • 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. – Valla Dec 22 '14 at 22:05
  • I don't think so reading your description. The notify is called automatically for you. It is part of Qt event loop. – McLeary Dec 23 '14 at 12:39
  • 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. https://code.google.com/p/exceptions4c/. Create an E4C context in your notify method in order to check for any signal exception. – McLeary Dec 23 '14 at 15:18
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/67560/discussion-between-valla-and-mcleary). – Valla Dec 23 '14 at 16:22
  • 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... – Valla Dec 23 '14 at 16:36
  • There is a "public:" missing to make the constructor public. – Adriel Jr Jan 16 '19 at 16:18
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
László Papp
  • 51,870
  • 39
  • 111
  • 135
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.

Anton Poznyakovskiy
  • 2,109
  • 1
  • 20
  • 38