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);
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?
I'm trying to connect a signal and a slot. I had it working, but I accidentally deleted a .h file. Now I tried to rewrite it, and everything's gone to hell. I've got:
#ifndef GAMEMANAGER_H
#define GAMEMANAGER_H
#include "gamepersistence.h"
class GameManager
{
Q_OBJECT
public:
GameManager();
~GameManager();
GamePersistence* _gamePersistece;
// other stuff
signals:
void refreshPlease();
void gameOverSignal();
};
#endif // GAMEMANAGER_H
And then I'm trying to connect it in another class:
GameWindow::GameWindow(QWidget *parent)
: QWidget(parent)
{
setFixedSize(900,200);
setWindowTitle(trUtf8("Amőba"));
//this->setStyleSheet("background-color: white;");
_gameManager = new GameManager();
// _gameManager->setFocusPolicy(Qt::StrongFocus);
connect(_gameManager, SIGNAL(gameOverSignal()), this, SLOT(gameOver()));
connect(_gameManager, SIGNAL(refreshPlease()), this, SLOT(refreshTable()));
//other stuff
}
This is in a class called GameWindow. Now I'm getting errors for the two connect lines:
error: no matching function for call to 'GameWindow::connect(GameManager*&, const char*, GameWindow* const, const char*)'
connect(_gameManager, SIGNAL(gameOverSignal()), this, SLOT(gameOver()));
What did I mess up in the header? I think I've rewritten it as it was...
Figured it out, I have to use the : public QObject base class.
in gamemanager.h add the public inheritance from QObject for signal and slot can be called.
class GameManager : public QObject{ //your class definition };
Im using a QML frontend for my C++ App which worked fine so far. However, I planned to tidy up my code and split functions into smaller classes
At first, my Property decleration looked like this:
class mainBoard : public QObject
{
Q_OBJECT
Q_PROPERTY(double baroAltitude MEMBER baroAltitude NOTIFY pressureChanged)
public:
explicit mainBoard(QObject *parent = 0);
void start();
private:
double baroAltitude = 0;
signals:
void pressureChanged();
};
Now, I do have this external class, with my getter method.
#include "pressuresensor.h"
class mainBoard : public QObject
{
Q_OBJECT
Q_PROPERTY(double baroAltitude READ pressureSensors.getBaroAltitude NOTIFY pressureSensors.pressureChanged)
public:
explicit mainBoard(QObject *parent = 0);
void start();
private:
pressureSensor pressureSensors;
};
But now, all I get is:
mainboard.h:25: Parse error at "pressureSensors"
error: [moc_mainboard.cpp] Error 1
Is there a better, or correct (because its working :D ) way for it?
thanks!
Q_PROPERTY does not support getters/setters methods which are not part of the class in question.
If you really want to keep the pressureSensor class you have to provide getters/setters in the mainBoard class and forward the calls.
class mainBoard : public QObject
{
Q_OBJECT
Q_PROPERTY(double baroAltitude READ getBaroAltitude)
public:
double getBaroAltitude() const {
return pressureSensors.getBaroAlitude();
}
private:
pressureSensor pressureSensors;
};
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.
I am a newbie in Qt and C++ programming. I have some problem in my program that i need a solution for.
I have two files MainWindow.h and ChatWindow.h, which contains two classes of MainWindow and ChatWindow.
This is chatwindow.h
namespace Ui {
class ChatWindow;
}
class ChatWindow : public QMainWindow
{
Q_OBJECT
public:
explicit ChatWindow(QWidget *parent=0);
~ChatWindow();
private slots:
void send_chat_fn(pjsua_call_id call_id);
void rcv_chat_fn(pjsua_call_id call_id);
void rcv_msg_fn(QString msg);
void on_pushButton_clicked();
void on_actionQuit_triggered();
private:
Ui::ChatWindow *ui;
};
And this is mainwindow.h
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
void add_item(QString buddy_uri);
signals:
void send_chat(pjsua_call_id call_id);
void rcv_chat(pjsua_call_id call_id);
void rcv_msg(QString msg);
private slots:
void on_actionAdd_Buddy_triggered();
void on_actionQuit_triggered();
void on_actionStatus_triggered();
void on_actionNew_Chat_triggered();
void on_action_Configuration_triggered();
void on_listWidget_doubleClicked(const QModelIndex &index);
private:
Ui::MainWindow *ui;
};
Now i want to connect signals from mainwindow.h to slots in chatwindow.h.
I have tried connection in the constructor of class ChatWindow, but it does not work (i think that is because connections work on instances not on classes). Instance of MainWindow class which i want to connect is in mainwindow.cpp. Defining instances of class ChatWindow in MainWindow gives error:
Cannot set parent, parent is in different thread
And if i create a new instance in Constructor of ChatWindow, then it doesnt connect to the desired instance.
Its a complete mess. Please help me through this.