0

We're using a really old version of Qt, 1.1, I think. Circa 2000. It's for in-house use only, so there's little concern to upgrade at this time. Program is built on Windows using Visual Studio 2005. I know very little of Qt, other than what I've been researching over the last couple days.

The (very basic) architecture is:

  • main() creates a QApplication instance.
  • main() also creates a pointer to a custom subclass of QWidget called Wizard.
  • Wizard creates a number of Controller objects, which are subclassed from QThread.

I am trying to implement a new class / thread, launched from main(), the purpose of which is to monitor a service and signal an action to be carried out in the Controller objects / threads.

My new class / Thread definition:

#include "qthread.h"

class ServiceMonitor : public QThread 
{
    Q_OBJECT

public:
   ServiceMonitor(int p) : port(p) {}
   ~ServiceMonitor() {};

private:
   void run();
   void TerminateProgram();

signals:
   void SomethingBadHappened();

private:
   int port;
};

And in my cpp file:

void ServiceMonitor::TerminateProgram()
{
   ...
   emit SomethingBadHappened();
   ...
}

When I compile the app, I receive a linker error:

error LNK2019: unresolved external symbol "protected: void __thiscall ServiceMonitor::SomethingBadHappened(void)"
 (?SomethingBadHappened@ServiceMonitor@@IAEXXZ) referenced in function "private: void __thiscall ServiceMonitor::TerminateProgram(void)"
 (?TerminateProgram@ServiceMonitor@@AAEXXZ) ServiceMonitor.obj  

I notice that all of our other objects (which have signals) are not derived from Qthread, so I have no examples to follow. The rest (which do use signals) are derived from QWidget or QObject). I notice those use the moc.exe in a custom compile step to generate an output file which is included in the project. I did try to run moc on the header containing the class above and including the output file, where I received:

Error   1   error C2039: 'className' : is not a member of 'QThread'
Error   2   error C3861: 'badSuperclassWarning': identifier not found
Error   3   error C2039: 'staticMetaObject' : is not a member of 'QThread'
Error   4   error C3861: 'activate_signal': identifier not found

What am I doing wrong?

EDIT:

Tried RA's proposal, worked a treat (Once I remembered to include qobject.h). Thanks!

New definition:

#include "qthread.h"
#include "qobject.h"

class ServiceMonitor : public QObject, public QThread
...
Jon
  • 1,675
  • 26
  • 57
  • 1
    You can only define signals, use the `Q_OBJECT` macro and run moc.exe on classes that inherit from `QObject`. The `QThread` class did not inherit from `QObject` prior to Qt 4.0, which is why you're getting errors. You can try to use multiple inheritance (i.e., `class ServiceMonitor : public QObject, public QThread` -- note that `QObject` must be first). – RA. Aug 14 '14 at 17:03
  • 1
    Can you post your updated code? The errors make it seem like you're not including `qobject.h`. – RA. Aug 14 '14 at 17:10
  • Yep, that did it. Repost your comment as an answer and I shall accept. Thank you! – Jon Aug 14 '14 at 17:19

2 Answers2

2

For versions of Qt prior to Qt 4.0, the QThread class did not inherit from QObject. As such, if you want to create a class derived from QThread that has signals, you must inherit from both QObject and QThread:

#include "qobject.h"
#include "qthread.h"

class ServiceMonitor : public QObject, public QThread 
{
    Q_OBJECT
    // Rest of class
};

Note that QObject must be listed as the first class derived from.

Also remember to run moc on the class and to compile the generated moc code.

RA.
  • 7,542
  • 1
  • 34
  • 35
0

The missing part is the implementation of all the signals, and of the staticMetaObject structure that's declared as part of Q_OBJECT macro. Those are generated by moc. Moc-ing of the headers would normally be handled by a Qt add-in for Visual Studio. Unfortunately, there are no Qt-5 add-ins for VS 2005.

Your options are, in order of decreasing desirability.

  1. Use qmake to generate a VS 2005 project file that invokes moc for you, and includes the necessary files. That would be the best way for you to use Qt.

  2. Manually run moc on all of the header files that contain the Q_OBJECT macro, and add the generated code to your project.

  3. Upgrade to at least VS 2008 (not Express), so that you can use the Qt 5 add-in.

  4. Try Qt 4, which has an add-in for VS 2005.

Since you can have multiple versions of Qt installed at the same time, you can pursue multiple approaches in parallel. For example, #1 and #4.

Kuba hasn't forgotten Monica
  • 95,931
  • 16
  • 151
  • 313
  • Thanks Kuba. We are stuck with VS 2005 and Qt 1 for the foreseeable future. moc is run on the headers and the resulting files included. It would be nice to update, but not an option at this time. – Jon Aug 14 '14 at 17:21
  • @Jon Are you serious? Qt 1? Wow. I missed it in the question! I'd love to port *that* to Qt 5. – Kuba hasn't forgotten Monica Aug 14 '14 at 17:23