Compiler errors on setter and getter functions in QT - c++

In the midst of making a test program I've come across a problem that has me boggled. I have googled and looked on here and haven't found an answer to the problem so thought I might just ask.
The issue: I get compiler errors on a getter and a setter function I made in QT. Basically I need to be able to set and get a QList object.
What am I overlooking? I think I might be doing something wrong with QList but I can't see what.
SliderArray.h
#ifndef SLIDERARRAY_H
#define SLIDERARRAY_H
#include <QWidget>
#include <QList>
#include <QSlider>
class SliderArray : public QWidget
{
Q_OBJECT
public:
explicit SliderArray(int sliders, QWidget *parent = 0);
~SliderArray();
//getter function for slider data
QList<int> GetSliderData();
//setter function for slider data
void SetSliderData(QList<int>);
private:
QList<int> integerList1; //Qlist Object to hold data
SliderArray.cpp
SliderArray::GetSliderData()
{
return integerList1;
}
SliderArray::SetSliderData(QList<int> datalist)
{
integerList1 = datalist;
}
these are the errors I get when I try to compile:
...\sliderarray.cpp:24: error: prototype for 'intSliderArray::GetSliderData()' does not match any in class 'SliderArray'
SliderArray::GetSliderData()
^
...\sliderarray.h:16: error: candidate is: QList<int> SliderArray::GetSliderData()
QList<int> GetSliderData();
^
...\sliderarray.cpp:29: error: prototype for 'int SliderArray::SetSliderData(QList<int>)' does not match any in class 'SliderArray'
SliderArray::SetSliderData(QList<int> datalist)
^
...\sliderarray.h:19: error: candidate is: void SliderArray::SetSliderData(QList<int>)
void SetSliderData(QList<int>);
^

In your cpp file you should have:
QList<int> SliderArray::GetSliderData()
{
return integerList1;
}
void SliderArray::SetSliderData(QList<int> datalist)
{
integerList1 = datalist;
}
This has nothing to do with Qt, you're just missing the return types.

Related

Cannot convert const object in Return

I'm not entirely sure what I'm doing incorrectly here. I have a class which contains a constant pointer to another class object. However I'm getting an error about not being able to convert the const (class object). What am I doing wrong? Is my code setup incorrect in the what I'm trying to do?
Error message: cannot convert 'const AppProfile' to 'AppProfile*' in return
I initially had this in my header file class AppProfile and i changed it to #include "appprofile.h" which helped remove another error.
I later will call run() which executes run on my AppProfile object.
header file
#ifndef APPITEM_H
#define APPITEM_H
#include <QObject>
#include <QUrl>
#include <QDir>
#include "appprofile.h"
class AppItem : public QObject
{
Q_OBJECT
public:
explicit AppItem(QObject *parent = nullptr);
explicit AppItem(const AppProfile &profile,
QObject *parent);
/// App Profile
AppProfile *profile() const;
signals:
public slots:
void run();
private:
const AppProfile m_profile;
};
#endif // APPITEM_H
cpp file
#include "appitem.h"
#include "appprofile.h"
AppItem::AppItem(QObject *parent) :
QObject(parent)
{
}
AppItem::AppItem(const AppProfile &profile,
QObject *parent) :
QObject(parent),
m_profile(profile)
{
}
QString AppItem::name() const
{
return m_name;
}
void AppItem::run()
{
AppProfile *profile = profile();
profile->run();
}
AppProfile *AppItem::profile() const
{
return m_profile;
}
UPDATE:
Follow up question reguarding the answer givens given...
To simply explain my intentions, I'm parsing a json file that contains data used to create the parent object AppItem. When this item is constructed, it takes in it's construct an AppProfile object. This object is only ever created once, at the time in which AppItem is created.
Knowing that, how would you suggest i move forward editing the original questions code relating to AppProfile. Assuming that's enough information. I appreciate you help. This is what the code looks like that I would use to create an AppItem
AppProfile *profile = new AppProfile();
AppItem *appItem = new AppItem(profile);
For starters either there is a typo in your code or the function is defined incorrectly
AppProfile *AppItem::profile() const
{
return m_profile;
}
Within the class the data member m_profile is not a pointer.
//...
private:
const AppProfile m_profile;
};
So if the declaration of the data member is valid then the function should look like
const AppProfile *AppItem::profile() const
{
return &m_profile;
}
Or if the data member declaration should look like
//...
private:
const AppProfile *m_profile;
};
then in any case the function shall return a pointer to constant data.
const AppProfile *AppItem::profile() const
{
return m_profile;
}
That is the error message implicitly says that there is a typo in your code
cannot convert 'const AppProfile' to 'AppProfile*' in return
And if you will update the typo in any case you may not discard the qualifier const for the pointer.

Qt - No matching function for connect?

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 };

Qt Undo/Redo implementation, can’t connect to a button

I post the question also in the Qt Forum, here
I am trying to implement an undo and redo commands in my application. I have a QTreeWidget and I’d like to let the user undo and redo an action (ex. change a value in a QTreeWidgetItem columns in the QTreeWidget and undo/redo it).
Here part of my code:
class A.h
class A : public QWidget
{
Q_OBJECT
public:
explicit A(...);
~A();
ChangeValueTreeCommand *commands;
QUndoStack *undoStack;
QPushButton *undoBtn;
QPushButton *redoBtn;
QString newValue;
void changeItem(QTreeWidgetItem* treeWidgetItemChanged, int col);
};
class A.cpp
A::A(...){
undoStack = new QUndoStack(this);
}
void A::changeItem(QTreeWidgetItem* treeWidgetItemChanged, int col){
....
commands = new ChangeValueTreeCommand(treeWidgetItemChanged, col, newValue);
connect(undoBtn, SIGNAL(clicked()), commands, SLOT(undo()));
undoStack->push(commands);
}
class Commands.h
#ifndef COMMANDS_H
#define COMMANDS_H
#include <QApplication>
#include <QUndoCommand>
#include <QTreeWidgetItem>
class ChangeValueTreeCommand : public QUndoCommand
{
public:
explicit ChangeValueTreeCommand(QTreeWidgetItem* treeWI = NULL, int c = 0, const QString changedV = "");
~ChangeValueTreeCommand();
QTreeWidgetItem* treeWItem;
const QString changedValue;
int col;
public slots:
void undo();
void redo();
};
#endif // COMMANDS_H
class Commands.cpp
#include "Commands.h"
ChangeValueTreeCommand::ChangeValueTreeCommand(QTreeWidgetItem* treeWI, int c, const QString changedV)
: treeWItem(treeWI), col(c), changedValue(changedV)
{}
ChangeValueTreeCommand::~ChangeValueTreeCommand(){}
void ChangeValueTreeCommand::undo()
{
const QString oldValue = treeWItem->text(col);
treeWItem->setText(col, oldValue);
}
void ChangeValueTreeCommand::redo()
{
treeWItem->setText(col, changedValue);
}
The problem is that when the user changes the value in the QTreeWidgetItem, it automatically appears the previous value. Moreover, I would like to connect the undo and redo functions to two buttons, but the compiler says that
1543: error: C2664: ‘QMetaObject::Connection QObject::connect(const QObject *,const char *,const QObject *,const char *,Qt::ConnectionType)‘ÿ: cannot convert parameter 3 from ‘ChangeValueTreeCommand *’ to ‘const QObject *’
Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
Can someone help me? Thx
Your undo and redo Buttons should call undoStack->undo() / undoStack->redo(). This will move the stack pointer and will call the undo/redo function of the current command.
See the Qt Documentation for a detailed Explanation: http://qt-project.org/doc/qt-4.8/qundostack.html#undo
Escpecially this part:
New commands are pushed on the stack using push(). Commands can be
undone and redone using undo() and redo(), or by triggering the
actions returned by createUndoAction() and createRedoAction().
QUndoStack keeps track of the current command. This is the command
which will be executed by the next call to redo(). The index of this
command is returned by index(). The state of the edited object can be
rolled forward or back using setIndex(). If the top-most command on
the stack has already been redone, index() is equal to count().

How to call a pure virtual base class method implemented by subclass function?

I have two classes: AbstractClass and SubClass.
This is basically my code (well, just some example code):
abstractclass.h
class AbstractClass
{
public:
AbstractClass();
void doSomething();
protected:
virtual void implementMe() = 0;
int a;
};
abstractclass.cpp
#include "abstractclass.h"
AbstractClass::AbstractClass(){}
void AbstractClass::doSomething()
{
implementMe(); // compiler error: "implementMe() was not declared in this scope"
a = 0; // same compiler error here...
}
subclass.h
#include "abstractclass.h"
class SubClass : public AbstractClass
{
public:
SubClass();
protected:
void implementMe();
};
subclass.cpp
#include "subclass.h"
SubClass::SubClass() {}
void SubClass::implementMe()
{
// do some stuff
}
In the AbstractClass, however, I keep getting a compiler error (for the virtual function as well as for the class variable):
implementMe() was not declared in this scope
The only way I found to get rid of this was to use forward-declaration:
void implementMe();
AbstractClass::doSomething()
{
implementMe();
}
I cannot believe that this is the correct way, though?
Thanks!
EDIT:
Ok, as my conceptual understanding of subclassing in C++ doesn't seem to be totally wrong (see the comments), I'm gonna share some of my original source code. Hopefully this will help to indentify the error.
This is my abstract / base class:
abstractenvironment.h
#ifndef ABSTRACTENVIRONMENT_H
#define ABSTRACTENVIRONMENT_H
#include <QObject>
class AbstractEnvironment : public QObject
{
Q_OBJECT
public:
AbstractEnvironment(QObject *parent = 0);
protected:
virtual void process() = 0;
quint32 counter;
private slots:
void handleTimeout();
};
#endif // ABSTRACTENVIRONMENT_H
abstractenvironment.cpp
#include "abstractenvironment.h"
#include <QTimer>
QTimer *myTimer;
AbstractEnvironment::AbstractEnvironment(QObject *parent) :
QObject(parent)
{
myTimer = new QTimer(this);
connect(myTimer, &QTimer::timeout, this, &AbstractEnvironment::handleTimeout);
myTimer->start(1);
counter = 0;
}
void handleTimeout()
{
process();
counter++;
}
And this is my subclass:
environment.h
#ifndef ENVIRONMENT_H
#define ENVIRONMENT_H
#include "abstractenvironment.h"
class Environment : public AbstractEnvironment
{
Q_OBJECT
public:
Environment(Controller *controller, QObject *parent = 0);
protected:
void process();
};
#endif // ENVIRONMENT_H
environment.cpp
#include "environment.h"
Environment::Environment(Controller *controller, QObject *parent) :
AbstractEnvironment(controller, parent) {}
void Environment::process()
{
// do something
}
PS: I've learned from the first part of this question and tried to compile the source code above inside Qt with MinGW. I get exactly two error messages (as expected):
..\untitled\abstractenvironment.cpp: In function 'void handleTimeout()':
..\untitled\abstractenvironment.cpp:17:13: error: 'process' was not declared in this scope
..\untitled\abstractenvironment.cpp:18:5: error: 'counter' was not declared in this scope
In case you want to try it yourself, I've zipped the Qt project and uploaded it to my Dropbox (of course I will remove this file at some point but the code is exactly the same as in the post above --> it's just for the sake of convenience, so you don't have to copy-paste it yourself)
EDIT: You just changed your question. So I can't tell if your original text was your actual source code or not. Good rule of thumb, paste your actual code rather than paraphrase it (then de-identify or reduce it if needed).
ORIGINAL ANSWER:
implementMe(); // compiler error: "implementMe() was not declared in this scope"
That is because doSomething() isn't declared properly in AbstractClass. You "declared" it in the base class with:
doSomething();
The compiler doesn't recognize AbstractClass::doSomething() out of line definition so nothing inside the implementation is resolved to the class scope.
Change that to:
void doSomething();
just like in your derived class.
and
AbstractClass::doSomething()
{
implementMe();
}
to
void AbstractClass::doSomething()
{
implementMe();
}
UPDATE:
void handleTimeout()
{
process();
counter++;
}
is a global function. That isn't the class implementation. It should be:
void AbstractClass::handleTimeout()
{
process();
counter++;
}
In abstractenvironment.cpp you define void handleTimeout(), which is non-member function and does not relate to AbstractEnvironment class. Thus, it doesn't look for AbstractEnvironment::process() and AbstractEnvironment::counter, but for ::process() and ::counter instead (which are not declared, hence the error).
Change it to void AbstractEnvironment::handleTimeout() and it should compile.

How to pass QList from QML to C++/Qt?

I'm trying to pass QList of integer from QML to C++ code, but somehow my approach is not working. With below approach am getting following error:
left of '->setParentItem' must point to class/struct/union/generic type
type is 'int *'
Any inputs to trouble shoot the issue is highly appreciated
Below is my code snippet
Header file
Q_PROPERTY(QDeclarativeListProperty<int> enableKey READ enableKey)
QDeclarativeListProperty<int> enableKey(); //function declaration
QList<int> m_enableKeys;
cpp file
QDeclarativeListProperty<int> KeyboardContainer::enableKey()
{
return QDeclarativeListProperty<int>(this, 0, &KeyboardContainer::append_list);
}
void KeyboardContainer::append_list(QDeclarativeListProperty<int> *list, int *key)
{
int *ptrKey = qobject_cast<int *>(list->object);
if (ptrKey) {
key->setParentItem(ptrKey);
ptrKey->m_enableKeys.append(key);
}
}
You CAN'T use QDeclarativeListProperty (or QQmlListProperty in Qt5) with any other type than QObject derived ones. So int or QString will NEVER work.
If you need to exchange a QStringList or a QList or anything that is an array of one of the basic types supported by QML, the easiest way to do it is to use QVariant on the C++ side, like this :
#include <QObject>
#include <QList>
#include <QVariant>
class KeyboardContainer : public QObject {
Q_OBJECT
Q_PROPERTY(QVariant enableKey READ enableKey
WRITE setEnableKey
NOTIFY enableKeyChanged)
public:
// Your getter method must match the same return type :
QVariant enableKey() const {
return QVariant::fromValue(m_enableKey);
}
public slots:
// Your setter must put back the data from the QVariant to the QList<int>
void setEnableKey (QVariant arg) {
m_enableKey.clear();
foreach (QVariant item, arg.toList()) {
bool ok = false;
int key = item.toInt(&ok);
if (ok) {
m_enableKey.append(key);
}
}
emit enableKeyChanged ();
}
signals:
// you must have a signal named <property>Changed
void enableKeyChanged();
private:
// the private member can be QList<int> for convenience
QList<int> m_enableKey;
};
On the QML side, simply affect a JS array of Number, the QML engine will automatically convert it to QVariant to make it comprehensible to Qt :
KeyboardContainer.enableKeys = [12,48,26,49,10,3];
That's all !