No matching constructor for initialization of 'QQmlListProperty<Player>' - qt

new bee here on QT.
I am trying to build an online example that used to work on QT5, but the compilation keeps failing on QT6. I keep getting this error and not sure why.
footballteam.cpp:55:12: No matching constructor for initialization of 'QQmlListProperty<Player>'
qqmllist.h:76:5: candidate constructor not viable:
no known conversion from 'int (*)(QQmlListProperty<Player> *)'
to 'QQmlListProperty<Player>::CountFunction'
(aka 'long long (*)(QQmlListProperty<Player> *)') for 4th argument
Code:
QQmlListProperty<Player> FootBallTeam::players()
{
return QQmlListProperty<Player>(this,this,&FootBallTeam::appendPlayer,
&FootBallTeam::playerCount,
&FootBallTeam::player,
&FootBallTeam::clearPlayers);
}
Classes:
class FootBallTeam : public QObject
{
Q_OBJECT
Q_PROPERTY(QString title READ title WRITE setTitle NOTIFY titleChanged)
Q_PROPERTY(QString coatch READ coatch WRITE setCoatch NOTIFY coatchChanged)
Q_PROPERTY(Player * captain READ captain WRITE setCaptain NOTIFY captainChanged)
Q_PROPERTY(QQmlListProperty<Player> players READ players NOTIFY playersChanged)
... bunch of stuff
private:
//Callback Methods
static void appendPlayer(QQmlListProperty<Player>*, Player*);
static int playerCount(QQmlListProperty<Player>*);
static Player* player(QQmlListProperty<Player>*, int);
static void clearPlayers(QQmlListProperty<Player>*);
....
class Player : public QObject
{
Q_OBJECT
Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
Q_PROPERTY(bool playing READ playing WRITE setPlaying NOTIFY playingChanged)
Q_PROPERTY(QString position READ position WRITE setPosition NOTIFY positionChanged)
public:
explicit Player(QObject *parent = nullptr);
QString name() const;
bool playing() const;
QString position() const;
void setName(QString name);
void setPlaying(bool playing);
void setPosition(QString position);
signals:
void nameChanged(QString name);
void playingChanged(bool playing);
void positionChanged(QString position);
private :
QString m_name;
bool m_playing;
QString m_position;
};
I looked into this thread, but did not help much.
Pass QQmlListProperty from QML to C++ as parameter
Any ideas why it does not compile on QT6?
thank you.

As pointed out by absolute.madnes, the fix was to change int to qsizetype
qsizetype FootBallTeam::playerCount(QQmlListProperty<Player> * list)
{
return reinterpret_cast<FootBallTeam*>(list->data)->playerCountCustom();
}
Player *FootBallTeam::player(QQmlListProperty<Player> * list, qsizetype index)
{
return reinterpret_cast<FootBallTeam*>(list->data)->playerCustom(index);
}

Related

using qt activex property value in js always return empty

I am buiding a qt axserver dll with a Qt property like :
class testDll : public QObject , public QAxBindable
{
Q_OBJECT
Q_CLASSINFO("ClassID", "{}")
Q_CLASSINFO("InterfaceID", "{}")
Q_CLASSINFO("EventsID", "{}")
Q_PROPERTY(QString name MEMBER m_name READ getName WRITE setName)
public:
testDll(QObject *parent = 0);
QString getName() const;
public slots:
void setName(QString v);
signals:
void nameChanged(QString v);
private:
QString m_name;
};
when I use this dll in a axcontainer I built for test, I can get the property value like this QString res = container->dynamicCall("name").toString();, but when I use this property in IE like this var name = testDll.name; console.log(name);, it always return empty.
I tried Q_PROPERTY(int number MEMBER m_number READ getNumber WRITE setNumber), it is ok to get the property value in IE using following two ways:
var dll = document.getElementById("testDll");
var num1 = dll.number;
console.log(num1);
var num2 = testDll.number;
console.log(num2);
I am new to activex and could not find good tutorial about qt activex developing. Can anyone help?
I finally solved this. It's actually kind stupid: name cannnot be used as Q_PROPERTY name. After I change the property name, it works.

using QList<T> in a connect( ) call

I am writing my first application in Qt4, basically using the books of Blanchette/Summerfield andSams 24 hours, and a lot of Qt search on internet.
my actual call is:
connect( thumbNailView,
SIGNAL(leftClicked(QListWidgetItem *)),
leftKeypointList,
SLOT(openItem(QListWidgetItem *)));
which gives the following error:
"no matching function for call to DAPPMainWindowWidget::connect(DAPPListWidget*&, const char [32], DAPPKeypointList*&, const char [29])"
I also connected this signal to another object which works flawless:
connect( thumbNailView,
SIGNAL(leftClicked(QListWidgetItem *)),
leftImage,
SLOT(openItem(QListWidgetItem *)));
Both leftImage and leftKeypointList are pointers to objects to a standard QWidget and and a custom object DAPPKeypointList : public QList with DAPPKeypoint holding index and position
of the keypoint.
My idea is that I cannot simply pass a pointer to QList sort of object the same way as I do a pointer to a standard Qwidget.
below follow:
in my DAPP.h
private:
DAPPKeypointList * leftKeypointList;
DAPPKeypointList * rightKeypointList;
and classes:
class DAPPKeypoint {
public:
DAPPKeypoint();
~DAPPKeypoint();
QPoint getKeypointPos();
void setKeypointPos(QPoint);
int getKeypointIndex();
void setKeypointIndex(int);
private:
QPoint keypointPos;
int keypointIndex;
};
class DAPPKeypointList : public QList<DAPPKeypoint> {
Q_OBJECT
public: DAPPKeypointList();
~DAPPKeypointList();
private slots:
void openItem(QListWidgetItem *);
};
in my cpp files:
DAPPKeypoint.cpp
#include "DAPP.h"
DAPPKeypoint::DAPPKeypoint(){}
DAPPKeypoint::~DAPPKeypoint(){}
QPoint DAPPKeypoint::getKeypointPos(){ return keypointPos; }
void DAPPKeypoint::setKeypointPos(QPoint kpPos){ keypointPos = kpPos; }
int DAPPKeypoint::getKeypointIndex(){ return keypointIndex; }
void DAPPKeypoint::setKeypointIndex(int kpIndex){ keypointIndex = kpIndex; }
DAPPKeypointList.cpp: (for the moment just a template ...)
#include "DAPP.h"
DAPPKeypointList::DAPPKeypointList(){}
DAPPKeypointList::~DAPPKeypointList(){}
void DAPPKeypointList:: openItem(QListWidgetItem *) {}
And DAPPMainWindowWidget.cpp :
Parts that are relevant (if you need more, let me know, but I think this is sufficient to have an idea of the problem):
leftKeypointList = new DAPPKeypointList;
rightKeypointList = new DAPPKeypointList;
leftImage = new DAPPImageWidget(leftImageLabel);
connect(thumbNailView,SIGNAL(leftClicked(QListWidgetItem *)) ,leftKeypointList ,SLOT(openItem(QListWidgetItem *)));
connect(thumbNailView,SIGNAL(leftClicked(QListWidgetItem *)) ,leftImage ,SLOT(openItem(QListWidgetItem *)));

Q_PROPERTY READ overloaded function

I have my C++/QT code
// .hpp
Q_PROPERTY(int Index READ Index WRITE setIndex NOTIFY IndexChanged)
public:
int Index() const;
int Index(int n) const;
void setIndex(int index):
//.cpp
setContextProperty(QStringLiteral("target"), this)
On the QML side i can access the index using target.Index. What is the syntax for using the taget.Index(int n) for example target.Index(8) gives me errors. Any examples for overloaded read function ?
What you are trying to do is sadly not really possible;
To begin with you'd need to add Q_INVOKABLE to the overloaded method (or make it a slot) in order to make it available to the QML engine:
Q_INVOKABLE int Index(int n) const;
That would mean that target.index is both a function and an int though, and that's of course not possible (isn't in QML/JavaScript and neither in C++). Qt seems to give priority to the property in this case, so you'll still get the "...is not a function" error.
You'll probably have to rename the overloaded function.
Note: The QML engine does handle function overloads (just make sure they are all either slots or marked with Q_INVOKABLE), just not having a function and a property of the same name. So you could have both target.Index() and target.Index(4), but you can't notify of changes that way.
There are two possible approaches:
You should:
Disambiguate the names exposed to QML.
Expose the method not given in Q_PROPERTY as invokable.
E.g.:
class Foo : public QObject {
Q_OBJECT
Q_PROPERTY(int Index READ Index WRITE setIndex NOTIFY IndexChanged)
// QML Interface
Q_INVOKABLE int Index1(int n) const { return Index(n); }
public:
// C++ interface
int Index() const;
int Index(int n) const;
void setIndex(int index);
Q_SIGNAL void IndexChanged();
};
Alternatively, if you're OK with using function interface from JavaScript in place of property interface, you need to take an optional argument via a QVariant. See this question for further details about overloading in QML. E.g.:
class Foo : public QObject {
Q_OBJECT
Q_PROPERTY(int IndexProp READ Index WRITE setIndex NOTIFY IndexChanged)
// QML interface
Q_INVOKABLE int Index(const QVariant & n) const {
if (n.isValid())
return Index(n.toInt());
return Index();
}
public:
// C++ interface
int Index() const;
int Index(int n) const;
void setIndex(int index);
Q_SIGNAL void IndexChanged();
};
The following are all valid then:
target.IndexProp = 5
foo = target.IndexProp
foo = target.Index()
foo = target.Index(2)

QT signal with struct in parameter

I have the class :
class SupervisionManager : public QThread {
Q_OBJECT public:
explicit SupervisionManager(ComAds* com, ComRegEtat* comEt,
ComRegOrdonnanceur* comOrdo,
QObject *parent = 0);
~SupervisionManager();
protected:
virtual void run();
private:
void actionFromPlc();
ComRegEtat::Antichoc antichoc;
signals:
void majAntichoc(ComRegEtat::Antichoc&);
};
and the implementation:
void SupervisionManager::run() {
manage=true;
while(manage)
{
actionFromPlc();
usleep(5000);
}
}
void SupervisionManager::actionFromPlc() {
antichoc.SAS = false;
emit majAntichoc(antichoc);
}
And I connect this signal with :
connect(manager, SIGNAL(majAntichoc(ComRegEtat::Antichoc&)),
preparation, SLOT(affichageAntichoc(ComRegEtat::Antichoc&)));
How do to emit a signal with a struct in its parameter list?
I think I have to use a QSignalMapper but I don't understand how.
In absolutely same way as you emit other things..
ComRegEtat::Antichoc myStruct;
.. some initialisation code
emit majAntichoc(myStruct);
I dont know for sure about latest Qt (after they changed signals/slot be templates based), but before 'emit' was just empty define, so you should look on emit like on function call...
With my code, the slot isn't called whereas the signal is emitted.
I found the solution :
signals:
void majAntichoc(ComRegEtat::Antichoc *);
and
slot :
void affichageAntichoc(ComRegEtat::Antichoc *);
And I don't have to use a QSignalMapper.
Thanks

Is it possible to emit a Qt signal from a const method?

In particular, I am implementing a QWizardPage ("MyWizardPage") for a QWizard, and I want to emit a signal ("sigLog") from my override of the QWizardPage::nextId virtual method.
Like so:
class MyWizardPage
: public QWizardPage
{
Q_OBJECT
public:
MyWizardPage();
virtual int nextId() const;
Q_SIGNALS:
void sigLog(QString text);
};
int MyWizardPage::nextId() const
{
Q_EMIT sigLog("Something interesting happened");
}
But when I try this, I get the following compile error on the Q_EMIT line:
Error 1 error C2662: 'MyWizardPage::sigLog' : cannot convert 'this' pointer from 'const MyWizardPage' to 'MyWizardPage &'
It is possible to emit a signal from a const method by adding "const" to the signal declaration, like so:
void sigLog(QString text) const;
I tested this and it does compile and run, even though you don't actually implement the signal as a normal method yourself (i.e. Qt is okay with it).
You may try to create another class , declare it as friend for your wizard page and add to wizard as a mutable member. after that you may emit it's signal instead of wizard's.
class ConstEmitter: public QObject
{
Q_OBJECT
...
friend class MyWizardPage;
Q_SIGNALS:
void sigLog(QString text);
};
class MyWizardPage
: public QWizardPage
{
Q_OBJECT
public:
MyWizardPage();
protected:
mutable CostEmitter m_emitter;
Q_SIGNALS:
void sigLog(QString text);
};
int MyWizardPage::nextId() const
{
Q_EMIT m_emitter.sigLog("Something interesting happened");
}
MyWizardPage::MyWizardPage()
{
connect(&m_emitter,SIGNAL(sigLog(QString)),this,SIGNAL(sigLog(QString)));
}
or you may just use
int MyWizardPage::nextId() const
{
Q_EMIT const_cast<MyWizardPage*>(this)->sigLog("Something interesting happened");
}
that is not recommended way, because const_cast is a hack, but it's much shorter :)

Resources