This class no problem:
#include <QThread>
class LiveImageItem : public QThread
{
Q_OBJECT
public:
LiveImageItem(QPixmap pimg);
signals:
public slots:
};
BUT this class get problem associated with "Q_OBJECT" macro defined in header file
#include <QGraphicsPixmapItem>
class LiveImageItem : public QGraphicsPixmapItem
{
Q_OBJECT //this line will generate many errors in compiling
public:
LiveImageItem(QPixmap pimg);
signals:
public slots:
};
both their cpp file is the same:
#include "LiveImageItem.h"
LiveImageItem::LiveImageItem(QPixmap pimg)
{
}
I thought every QT object essentially inherited from QObject so if I inherit any of the subclass of QObject, I could have all the magics QObject offers. The 2nd version of the above (which is inherited from, say, QGraphicsPixmapItem) seems proved I was wrong. It turns out to be having lots of errors while compiling, all from moc files(automatically generated by QT). What happens?
Some of these errors are:
[qobject.h] error: 'QScopedPointer QObject::d_ptr' is
protected
[moc_LiveImageItem.cpp] error: within this context
...
According to the documentation QGraphicsPixmapItem is not a QObject, thus you cannot treat it as if it is. I would try to extend your class inheritance and do:
class LiveImageItem : public QObject, public QGraphicsPixmapItem
{
Q_OBJECT //this line will generate many errors in compiling
[..]
As #vahancho said, QGraphicsPixmapItem is not a QObject. In fact, that can be said of most of the QGraphics*Item classes.
However, if you want to use signals and slots with QGraphicsSystem classes, you can inherit from QGraphicsObject: -
class LiveImageItem : public QGraphicsObject
{
Q_OBJECT
public:
private:
QPixmap m_pixmap;
};
You would then override the paint function in this class and draw the pixmap from there.
Related
I would like to share signals and possibly slot implementations among different classes, but it seems Qt does not allow this.
Basically I would like to have something like:
class CommonSignals
{
signals:
void mysignal();
};
class A :
public QObject,
public CommonSignals
{
Q_OBJECT
public:
void doSomething()
{
emit mysignal();
}
};
class B :
public QObject,
public CommonSignals
{
Q_OBJECT
public:
B()
{
connect(&a, &A::mysignal, this, &B::mysignal);
}
A a;
};
So that when for some reason A emits a signal B emits the same signal too. This to avoid useless code replication and improve maintainability.
Any ideas?
PS I've tried also with virtual inheritance but I've got classical qmake problems
You cannot do this. QObject cannot be used with multiple inheritance of multiple QObject bases. Only the first inherited class can be a QObject. See:
https://doc.qt.io/qt-5/moc.html#multiple-inheritance-requires-qobject-to-be-first
Since you need both base classes to be a QObject (CommonSignals provides signals, it would need to be a QObject), you're out of luck. Your only option here is using plain old macros:
#define COMMON_SIGNALS \
void signal1(); \
void signal2();
class A: public QObject
{
Q_OBJECT
public:
// ...
signals:
COMMON_SIGNALS
};
class B: public QObject
{
Q_OBJECT
public:
// ...
signals:
COMMON_SIGNALS
};
The core issue with all this is that Qt uses moc to generate the underlying code for signals and slots. However, moc is just a simple preprocessor that doesn't understand most of C++.
You could use Verdigris to get rid of moc:
https://github.com/woboq/verdigris
This allows you to have templated QObject classes, for example. I have not tried it myself and thus don't know if it actually allows multiple inheritance. Might be worth looking into.
Why not just move the inheritance from QObject away from the derived classes A and B and into CommonSignals...
class CommonSignals: public QObject {
Q_OBJECT;
signals:
void mysignal();
};
class A: public CommonSignals {
Q_OBJECT;
public:
void doSomething ()
{
emit mysignal();
}
};
class B: public CommonSignals {
Q_OBJECT;
public:
B ()
{
connect(&a, &A::mysignal, this, &B::mysignal);
}
A a;
};
Will that not work for you?
Hey guys I know there are already some threads for this question but I think I made none of the mistakes others did which led to the problem. So here is my code:
#include "consolerender.h"
consoleRender::consoleRender(QObject *parent) :
QObject(parent) {
connect(Enviroment::instance, &Enviroment::enviromentChanged,
this, &consoleRender::renderField);
}
And the header:
class consoleRender : public QObject
{
Q_OBJECT
public:
explicit consoleRender(QObject *parent = 0);
public slots:
void renderField();
};
And the Enviroment.h
class Enviroment : public QObject
{
Q_OBJECT
public:
static Enviroment& instance();
virtual ~Enviroment();
//stuff...
signals:
void enviromentChanged();
I already tried to do the connect in a separate class, I tried to use the old connect syntax (SIGNAL/SLOT(function)) and tried it with >>all<< my classes inheriting from QObject but it showed the same error. Also it says something that the function expects 3 arguments but gets 4. and seems to point at the connect(...renderField). I heard of a solution to just do all of that in the MainWindow class but that is not an option for me.
You have to pass the instance pointer:
connect(&Enviroment::instance(), &Enviroment::enviromentChanged,
this, &consoleRender::renderField);
I have a class MyClass with:
- private:
pushButton *button;
void connectSignalAndSlot();
- private slot:
void buttonAction();
I want to connect these in MyClass using connectSignalAndSlot(), like so:
void MyClass::connectSignalAndSlot()
{
QObject::connect(button,SIGNAL(clicked()),this,SLOT(buttonAction()));
}
This gives me an error of
no matching function for call to 'QObject::connect(QPushButton*&, const char*, MyClass* const, const char*)';
If I inherit QObject with MyClass, the program compiles and starts, but then I get the following issues displayed in my Application Output pane:
QObject::connect: No such slot QObject::buttonAction() in ..\MyProject\myclass.cpp:48
Do I have to make the button and slot public and use them in the MainWindow class only? Is there no way to keep this at the MyClass level?
Thanks for your help!
You must have MyClass inherit from QObject AND add Q_OBJECT macro in your MyClass definition (header file) to have slots/signals work.
class MyClass : public QObject
{
Q_OBJECT
public:
....
};
Inheriting QObject is the right way, but your still missing Qt-Meta Object Code. Your header-file for your class should look like this:
#ifndef MYCLASS_H
#define MYCLASS_H
class MyClass : public QObject {
Q_OBJECT
// your methods, variables, slots and signals
}
#endif
Don't forget to create the moc file, the easiest way is to use qmake or the QtCreator IDE.
I have a big problem with my classes: I will use the Q_OBJECT macro in my subclasses. But if I define Q_OBJECT in my subclasses, it throws an exception. This is the exception:
undefined reference to `vtable for SubClassOne'
undefined reference to `vtable for SubClassTwo'
My SubClassOne and SubClassTwo inherits from BaseClass.
Here some Code: (All #includes are correct)
\\baseclass.h
class BaseClass
{
public:
BaseClass(QWidget *widget=0);
QHBoxLayout *mainLayout;
};
\\subclassone.h
class SubClassOne : public BaseClass, public QWidget
{
Q_OBJECT
public:
explicit SubClassOne(QWidget *widget=0);
};
\\subclasstwo.h
class SubClassTwo : public BaseClass, public QDialog
{
Q_OBJECT
public:
explicit SubClassTwo(QWidget *dialog=0);
};
Here comes the .cpp Files
//baseclass.cpp
BaseClass::BaseClass(QWidget *widget)
{
mainLayout = new QHBoxLayout();
}
//subclassone.cpp
SubClassOne::SubClassOne(QWidget *widget):BaseClass(widget)
{
setWindowTitle("Widget");
}
//subclasstwo.cpp
SubClassTwo::SubClassTwo(QWidget *dialog):BaseClass(dialog)
{
setWindowTitle("Dialog");
QPushButton *btn = new QPushButton();
QObject::connect(btn,SIGNAL(clicked()),SLOT(close()));
mainLayout->addWidget(btn);
setLayout(mainLayout);
}
main.cpp
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
SubClassTwo *s = new SubClassTwo();
s->show();
return a.exec();
}
How can I use Q_OBJECT in my subclasses?
Your Q_OBJECT placement is fine in your code.
What you are hitting is that you forgot to include the generated moc file in your source such as:
baseclass.cpp (at the end of the file)
#include "baseclass.moc"
subclassone.cpp (at the end of the file)
#include "subclassone.moc"
subclasstwo.cpp (at the end of the file)
#include "subclasstwo.moc"
You need to make sure moc is generating these files for you though. You have not shown your buildsystem yet.
Also, please make sure to have one header and source file per "Q_OBJECT" classes. It is not strictly necessary, but it is a good practice.
You can of course resolve that at link time as well, but you will need to do either of those.
Moreover, once you have multiple inheritance, at least with Qt 4, you will need to inherit from the QObject subclass first, which is QWidget in your case. You can find the correct inheritance below.
subclassone.h
class SubClassOne : public QWidget, public BaseClass
subclasstwo.h
class SubClassTwo : public QDialog, public BaseClass
etc. Hope it helps.
Q_OBJECT must be the firs declaration in your class and any class inheriting QObject must be first in the list
class SubClassOne : public QWidget, public BaseClass
{
Q_OBJECT
public:
explicit SubClassOne(QWidget *widget=0);
};
\\subclasstwo.h
class SubClassTwo : public QDialog, public BaseClass
{
Q_OBJECT
public:
explicit SubClassTwo(QWidget *dialog=0);
};
you also need to run the moc on the header to generate the code needed to implement the slots and signals
I creati a simple class which extends two classes QObject and QThread.
When I compile it with MOC compiler there is an error:
expected class-name before ‘{’ token
Class started with this code:
class QSmartecVideoAudio : public QObject, public QThread
{
Q_OBJECT
...
};
I implement run method but it doesnot work.
I include qthread.h at the beginning.
Looks like an include issue. Try to add:
#include <QThread>
#include <QObject>
before your class definition.
QThread inherits QObject already, so you must not inherit from QObject.
try:
class QSmartecVideoAudio : public QThread
{
Q_OBJECT
...
};