C++ initializing a private variable class into another class - c++

I'm trying to init my private variable "DressMen black" into class Dialog/QT
class Dialog : public QDialog
{
Q_OBJECT
public:
explicit Dialog(QWidget *parent=0,DressMen b);
~Dialog();
........
public slots:
........
private slots:
.............
private:
Ui::Dialog *ui;
..........
DressMen black;
..........
};
And my DressMen class .h is
class DressMen {
public:
DressMen();
~DressMen(void);
DressMen(std::string name);
.................
}
DressMen.cpp is
DressMen::DressMen()
{
//set values for default constructor
..................
}
DressMen::DressMen(std::string name){
setType(name);
if(name=="black1"){
......
}
}
Now in my Dialog::Dialog I want init my DressMen black1 private variable equal to
- DressMen black("black1");
so I write
Dialog::Dialog(QWidget *parent,DressMen b) : QDialog(parent),ui(new Ui::Dialog),black(b("black1")) {
.....
}
but the compiler error me
dialog.h:23: error: default argument missing for parameter 2 of 'Dialog::Dialog(QWidget*, DressMen)'
explicit Dialog(QWidget *parent=0,DressMen b);
I don't understand because I'm in practice for C++ ......
thanks

As indicated by Brian Bi, you must either specify a default value for DressMen or you must make your DressMen the first argument. You could do the following:
class Dialog : public QDialog
{
Q_OBJECT
public:
explicit Dialog(QWidget *parent=0, DressMen b = DressMen("black1"));
...
};
Or you could do this:
// Dialog.h
class Dialog : public QDialog
{
Q_OBJECT
public:
explicit Dialog(QWidget *parent=0, DressMen b = DressMen());
...
};
// DressMen.h
class DressMen
{
public:
DressMen(std::string name = "black1");
...
};
The solution that makes the most sense depends on how you expect Dialog and DressMen to be used.

Related

New method to MainWindow is not visible

I have added st() function to my MainWindow class. But why I can't call it?
Got error:
error: 'class Ui::MainWindow' has no member named 'st'
ui->st();
^
*.h
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
void st();
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void on_MainWindow_iconSizeChanged(const QSize &iconSize);
void on_pushButton_4_clicked();
private:
Ui::MainWindow *ui;
};
*.cpp
void MainWindow::st()
{
}
void MainWindow::on_pushButton_4_clicked()
{
ui->st();
}
You added method st to MainWindow class, but attempting to call method st on object ui which type is Ui::MainWindow - Qt autogenerated class.
If you want to call st method in on_pushButton_4_clicked then ui->st() should be replaced with st().

Adding options to existing Q_PROPERTY from base class only in dereived class

I have a very simple base class which defines a normal Q_PROPERTY with READ and NOTIFY (WRITE is not in all dereived implementations possible).
class BaseClass : public QObject {
Q_OBJECT
Q_PROPERTY(QStringList someEntries READ someEntries NOTIFY someEntriesChanged)
public:
explicit BaseClass(QObject *parent = Q_NULLPTR) : QObject(parent) {}
virtual ~BaseClass() {}
virtual QStringList someEntries() const = 0;
void processEntries() {
for(auto entry : someEntries()) {
//process entry
}
}
Q_SIGNALS:
void someEntriesChanged(const QStringList &someEntries);
};
Now I have 2 dereiving classes, of which one supports only one entry (SingleItem) and the other one supports multiple entries (MultiItem).
SingleItem converts the one QString-member to a QStringList when requested and allows setting it using the differently called property (theEntry):
class SingleItem : public BaseClass {
Q_OBJECT
Q_PROPERTY(QString theEntry READ theEntry WRITE setTheEntry NOTIFY theEntryChanged);
public:
explicit SingleItem(QObject *parent = Q_NULLPTR) : BaseClass(parent) {}
virtual ~SingleItem() {}
const QString &theEntry() const { return m_theEntry; }
void setTheEntry(const QString &theEntry) {
if(m_theEntry != theEntry)
Q_EMIT theEntryChanged(m_theEntry = theEntry);
}
// BaseClass interface
QStringList someEntries() const Q_DECL_OVERRIDE
{ return QStringList { m_theEntry }; }
Q_SIGNALS:
void theEntryChanged(const QString &theEntry);
private:
QString m_theEntry;
};
MutliItem stores a QStringList (for someEntries). I would like to write into that QStringList using the property defined in BaseClass. But I dont know how to add the WRITE option to the already defined Q_PROPERTY.
class MultiItem : public BaseClass {
Q_OBJECT
//Somehow add the setSomeEntries method to the property?
public:
explicit MultiItem(QObject *parent = Q_NULLPTR) : BaseClass(parent) {}
virtual ~MultiItem() {}
void setSomeEntries(const QStringList &someEntries) {
if(m_someEntries != someEntries)
Q_EMIT someEntriesChanged(m_someEntries = someEntries);
}
// BaseClass interface
QStringList someEntries() const Q_DECL_OVERRIDE{ return m_someEntries; }
private:
QStringList m_someEntries;
};
I cannot add the WRITE option in BaseClass because it would violate the meaning. Not every object of BaseClass allows setting that property but objects of MultiItem should be written only using that property.
Is this somehow possible without declaring a WRITE option to a virtual ... = 0 in BaseClass that just logs a warning when called in SingleItem?

How to use the creating class` methods from the created class?

I have a question:
I have a class userinterface that has a class MoveSeries. From MoveSeries I want to have access to the methods of my class userinterface. In this example I want to have access to the method get_MoveCurve_Delta() of userinterface. How do I get access to the creating class (userinterface) from the created class (MoveSeries ? I tried the Signal-Slot-Approach but since I have to use several methods of userinterface several times this makes lots of signal-slots...
here is my code:
Userinterface.h:
class UserInterface : public QMainWindow
{
Q_OBJECT
public:
UserInterface(QWidget *parent = 0, Qt::WFlags flags = 0);
~UserInterface();
...
private:
double MoveCurve_Delta;
MoveSeries *MOVE_SERIES ;
public:
void set_MoveCurve_Delta( double val) { MoveCurve_Delta = val;}
double get_MoveCurve_Delta() { return MoveCurve_Delta ;}
}
Userinterface.cpp:
UserInterface::UserInterface(QWidget *parent, Qt::WFlags flags) :
QMainWindow(parent, flags)
{
ui.setupUi(this);
...
MOVE_SERIES = new MoveSeries( this);
}
MoveSeries.h:
class MoveSeries : public QDialog
{
Q_OBJECT
public:
explicit MoveSeries(QWidget *parent = 0);
~MoveSeries();
...
MoveSeries.cpp:
MoveSeries::MoveSeries(QWidget *parent) :
QDialog(parent),ui(new Ui::MoveSeries)
{
ui->setupUi(this);
this->parent = parent;
parent->set-MoveSeries_Delta_Val();
}
Rather than assume that the parent QWidget in MoveSeries is UserInterface, you can also require that it is.
MoveSeries.h:
class UserInterface; // only need a forward declaration
class MoveSeries : public QDialog
{
Q_OBJECT
public:
explicit MoveSeries(UserInterface *parent = 0);
~MoveSeries();
...
UserInterface * uiparent;
}
MoveSeries.cpp:
#include "Userinterface.h" // include the header where it is required
MoveSeries::MoveSeries(UserInterface *parent) :
QDialog(parent), ui(new Ui::MoveSeries), uiparent(parent)
{
ui->setupUi(this);
uiparent->set-MoveSeries_Delta_Val();
}
It looks like you want to cast the parent to the class you want:
static_cast<UserInterface *>(parent)->get_MoveCurve_Delta();
Bear in mind that this could be dangerous as it makes an assumption about the type of the parent.
If you want only UserInterface be the parent of MoveSeries, say so:
explicit MoveSeries(UserInterface *parent = 0);
If you want any widget to be able to act as the parent, you cannot access UserInterface methods because the parent does not necessarily have them.

Qt property outside of base class

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

how to implement OOP using QT

this is a simple OOP QT question.
my app consists of main window (QMainWindow) and a table (QTableWidget).
in the main window i have arguments and variables which i would like to pass to the table class, and to access methods in main widnow class from the table class, how should i do it ?
mainwindow.h
class MainWindow : public QMainWindow {
Q_OBJECT
private:
int a;
int b;
Spreadsheet *spreadsheet;
public:
void set_a(int);
void set_b(int);
spreadsheet.h
class Spreadsheet : public QTableWidget {
Q_OBJECT
public:
Spreadsheet(QWidget *parent = 0);
atm i define Spreadsheet like this:
spreadsheet = new Spreadsheet(this);
and i'd like to access set_a() from spreadsheet.cpp...
You should consider a different design, you are tightly coupling your code.
Maybe something like the following...
class Spreadsheet : public QTableWidget
{
Q_OBJECT
signals:
void aValueChanged(int value);
void bValueChanged(int value);
public:
void doSomething()
{
emit aValueChanged(100);
}
};
class MainWindow : public QMainWindow
{
public:
MainWindow() :
a(0),
b(0)
{
connect(&spreadsheet, SIGNAL(aValueChanged(int)), this, SLOT(setA(int)));
connect(&spreadsheet, SIGNAL(bValueChanged(int)), this, SLOT(setB(int)));
spreadsheet.doSomething();
}
slots:
void setA(int value) { a = value; }
void setB(int value) { b = value; }
private:
Spreadsheet spreadsheet;
int a;
int b;
};
This is completely untested but gives you an idea.
You can use the parent() method in the Spreadsheet object to get a pointer to your MainWindow.
For example,
// spreadsheet.cpp
MainWindow* mainWindow = (MainWindow*) this->parent();
mainWindow->set_a(123);
Of course, the parent object passed to Spreadsheet's constructor should be your MainWindow instance for this to work.
However, you should seriously consider oscode's suggestion, since it also points you towards creating a more Qt-like API.