Here is my sample code:
class hoho : public QObject
{
Q_OBJECT
public:
hoho()
{
httpFetch = new HttpFetch(QUrl("http://www.google.com/"));
connect(httpFetch, SIGNAL(Fetched()), this, SLOT(PrintData(QByteArray)));
}
void PrintData(QByteArray http)
{
qDebug()<<http;
}
HttpFetch *httpFetch;
};
When I try to compile this, following error pops up
1>main.cpp(15): error C2243: 'type cast' : conversion from 'HttpFetch *' to 'const QObject *' exists, but is inaccessible
This error comes as the class is derived from QObject (which is necessary for signal and slot mechanism).
Can anyone tell me how to fix this?
You probably did not derive HttpFetch publicly, but privately from QObject. So just change
class HttpFetch : QObject { // ...
to
class HttpFetch : public QObject { // ...
and it should work.
If your design requires to make the inheritance non-public (I had this requirement because I inherited from a QWidget for a multithreading purpose and didn't want to expose all functions to the user), you can do this:
class FilesQueueQList : protected QWidget
{
Q_OBJECT
public:
using QWidget::QObject; //This is the solution!
//...
}
Now the members of QWidget are private/protected, but QObject is accessible as public.
Did you forget the Q_OBJECT macro in your class HttpFetch ?
Can I see your class HttpFetch ?
Related
I have a command inherited from QUndoCommand:
class ImportEntityCommand : public QUndoCommand
{
// ...
private:
QString m_importedEntityName;
Importer *m_importer;
// ...
}
The redo method kicks off a QProcess:
void ImportEntityCommand::redo()
{
if (/* Import is already done before */) {
// ...
} else {
// Import finish is handled by a slot
m_importer->import(m_url);
}
}
Signal-slot connection is composed in command constructor:
ImportEntityCommand::ImportEntityCommand(EditorSceneItemModel *sceneModel, const QUrl &url) :
, m_importer(new Importer(/* ... */))
{
// Importer would start a QProcess which runs asynchronously and emits a signal
// that's why I have to handle the signal by a slot
QObject::connect(m_importer
, &Importer::importFinished
, this
, &ImportEntityCommand::handleImportFinish
);
}
The signal emitted by the process is handled like this:
void ImportEntityCommand::handleImportFinish(const QString name)
{
m_importedEntityName = name;
}
But I'm receiving such error while compiling:
C:\Qt\Qt5.12.9\5.12.9\msvc2017_64\include\QtCore\qobject.h:250: error: C2664: 'QMetaObject::Connection QObject::connectImpl(const QObject *,void **,const QObject *,void **,QtPrivate::QSlotObjectBase *,Qt::ConnectionType,const int *,const QMetaObject *)': cannot convert argument 3 from 'const ImportEntityCommand *' to 'const QObject *'
The error point is that:
cannot convert argument 3 from 'const ImportEntityCommand *' to 'const QObject *'
I'm inhering my ImportEntityCommand class from QUndoCommand which in turn inherits from QObject, I guess.
Question
Therefore, for some reason, Qt won't allow me to handle signals inside a command inherited from QUndoCommand.
Is this limitation intentional?
What are my options to work around this limitation? What is the standard procedure?
I'm inhering my ImportEntityCommand class from QUndoCommand which in
turn inherits from QObject, I guess.
QUndoCommand does not inherit from QObject see:
https://doc.qt.io/qt-5/qundocommand.html
Compared to a QWidget for example, that does inherit from QObject.
https://doc.qt.io/qt-5/qwidget.html
If you want your importer to handle signals and slots you can just inherit from QObject:
class importer: public QObject
{
Q_OBJECT
public:
...
private:
...
}
and you can connect to a lambda e.g.:
QObject::connect(m_importer
, &Importer::importFinished
[&]() { this->handleImportFinish() }
);
Could you not just use composition to place a QObject derived class instance in the ImportEntityCommand? You could then connect the signal to the QObject derived class which would then call in to ImportEntityCommand to do the work.
class SignalReceiver : public QObject
{
Q_OBJECT
public:
SignalReciever(ImportEntityCommand *iec) : QObject()
, _iec(iec)
{}
public slot:
void handleImportFinished(QString url)
{
if (this->_iec) this->_iec->handleImportFinished(url);
}
private:
ImportEntityCommand *_iec{nullptr};
};
Then in your ImportEntityCommand, you would create a SignalReceiver and connect it to the signal:
class ImportEntityCommand : public QUndoCommand
{
// ...same as before, then
private:
QScopedPointer<SignalReceiver, QScopedPointerDeleteLater> _signalReceiver;
};
// in the ImportEntityCommand constructor
this->_signalReceiver.reset(new SignalReceiver(this));
QObject::connect(this->importer,
&Importer::importFinished,
this->_signalReciver.data(),
&SignalReceiver::handleImportFinished);
We can't get around from passing a raw pointer of ImportEntityCommand to SignalReceiver since ImportEntityCommand has to live in the undo stack. On the other hand, using a QScopedPointer for the receiver ensures that it is cleaned up properly when the undo stack deletes the ImportEntityCommand instance. Just remember to always specify the QScopedPointerDeleteLater when wrapping a QObject derivative -- especially one that is catching signals.
I have a slot that is triggered by a QFutureWatcher. I'm trying to cast the sender to get the results
QFutureWatcher<QPair<QImage,QString>>* QFW = qobject_cast<QFutureWatcher<QPair<QImage,QString>>*>(sender());
but keep getting
error: static assertion failed: qobject_cast requires the type to have a Q_OBJECT macro
I'm not really sure what's wrong here, these are all Qt built-in types, so what am I doing wrong?
You have to put Q_OBJECT in the Class Definition, like this:
class MyClass : public QObject
{
Q_OBJECT
// ^^^^^^^^^^
public:
MyClass();
/*...*/
}
I am getting this error :
/MyApp/company.cpp:3: error: no matching function for call to ‘DepList::DepList(Company*, Company*)’
Company::Company(QObject *parent) : QObject(parent),dep_cache(this,this),search_results(this,this)
^
/MyApp/company.h:14: In file included from ../../../../MyApp/company.h:14:0,
/MyApp/company.cpp:1: from ../../../../MyApp/company.cpp:1:
/MyApp/deplist.h:34: candidate: DepList::DepList(QAbstractItemModel*, Company*)
explicit DepList(QAbstractItemModel *parent = 0,Company* p_company=0);
/MyApp/deplist.h:34: note: no known conversion for argument 1 from ‘Company*’ to ‘QAbstractItemModel*’
^
when compiling the constructor code for Company class:
Company::Company(QObject *parent) : QObject(parent),dep_cache(this,this),search_results(this,this)
{
// .... some intialization stuff here, unrelated to the error
}
and it only happens with classes where the parent is QAbstractItemModel. With other classes , parents of QObject I am using initialization lists without errors. The error appeared when I added initialization lists.
this is how search_results is declared inside Company class:
class Company : public QObject {
...
DepList search_results;
...
}
and it's constructor is:
DepList::DepList(QAbstractItemModel *parent,Company* p_company) : QAbstractItemModel(parent)
{
company=p_company;
}
What is the problem here , and why it only happens with QAbstractItemModel?? QAbstractItemModel is also a child of QObject and I have no problems with initialization lists in QObject classes. I had a thought of casting , but would it be safe ?
Company is a QObject-derived:
class Company : public QObject {
Q_OBJECT
...
explicit Company(QObject *parent = 0);
...
};
But DepList is a QAbstractItemModel-derived:
class DepList : public QAbstractItemModel
{
...
explicit DepList(QAbstractItemModel *parent = 0,Company* p_company=0);
...
}
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 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
...
};