Multiple inheritance in Qt - c++

How to inherit QLabel and QPushButtton too, what I tried shows error messages
/home/test.cpp:206: error: reference to 'setText' is ambiguous
setText(text);
^
Here is what I tried:
class virtualLabel: virtual public QLabel
{
Q_OBJECT
public:
explicit virtualLabel(const QString& text="", QWidget* parent=0){}
~virtualLabel(){}
};
class virtualPushButton: virtual public QPushButton
{
Q_OBJECT
public:
explicit virtualPushButton(const QString& text="", QWidget* parent=0){}
~virtualPushButton(){}
};
class customLabel : public virtualLabel, public virtualPushButton
{
Q_OBJECT
// Q_DECLARE_INTERFACE
//Q_INTERFACES(YourInterface OtherInterface)
public:
explicit customLabel(const QString& text="", QWidget* parent=0);
~customLabel();
QString folderName;
};
Any help appreciated Thank You

You don't.
Apart from the issue with ambiguity you will have a lot more issues.
From the Qt documentation on moc:
Virtual inheritance with QObject is not supported.
(Trust them on that)
Rather use composition and expose the signals, slots and functions you need.
class customLabel : public QWidget
{
Q_OBJECT
public:
explicit customLabel(const QString& text="", QWidget* parent=0);
~customLabel();
protected:
QPushButton* button;
QLabel* label;
};

Related

What do "signals:" and "private slots:" mean in the following code?

In this link there is the following code:
class FileDownloader : public QObject
{
Q_OBJECT
public:
explicit FileDownloader(QUrl imageUrl, QObject *parent = 0);
virtual ~FileDownloader();
QByteArray downloadedData() const;
signals:
void downloaded();
private slots:
void fileDownloaded(QNetworkReply* pReply);
private:
QNetworkAccessManager m_WebCtrl;
QByteArray m_DownloadedData;
};
What do the colons in signals: and private slots: mean? Code generally uses this symbol for labels but these don't seem like labels.

Using signals into a class which is inheriting from QObject

I'm asking if there is a way to use signals in a class which inherits from QObject like this:
mysuperclass.cpp
#include "mysuperclass.h"
MySuperclass::MySuperclass(quint16 port, QObject *parent) :
QObject(parent), port(port)
{
this->connected = false;
}
mysuperclass.h
#include <QAbstractSocket>
class MySuperclass: public QObject
{
Q_OBJECT
public:
explicit MySuperclass(quint16 port = 0, QObject *parent = 0);
signals:
//there is nothing here
public slots:
virtual void newValue(){qDebug() << "newValue";}
virtual void connectionEstablished(){qDebug() << "connectionEstablished";}
virtual void disconnected(){qDebug() << "disconnected";}
protected:
QAbstractSocket* networkSocket;
quint16 port;
bool connected;
};
mysubclass.cpp
#include <QTcpSocket>
#include <QHostAddress>
MySubClass::MySubClass(quint16 ServerPort, QObject *parent) :
MySuperClass(ServerPort, parent)
{
this->networkSocket = new QTcpSocket(this);
...
connect(this->networkSocket, SIGNAL(connected()),this,
SLOT(connectionEstablished()));
connect(this->networkSocket, SIGNAL(disconnected()),this,
SLOT(disconnected()));
connect(this->networkSocket, SIGNAL(readyRead()),this, SLOT(newValue()));
}
mysubclass.h
#include <QObject>
#include "mysuperclass.h"
class MySubClass: public MySuperClass
{
public:
MySubClass(quint16 ServerPort, QObject* parent=0);
public slots:
void newValue();
void connectionEstablished();
void disconnected();
};
You must include the Q_OBJECT macro in the derived class too (but don't derive from QObject again). The macro is only mandatory if the derived class declares signals or slots. For emitting parent's signals or connecting with parent's slots it is not necessary (it also means that it is not necessary to re-define already existing signals or slots).
From Qt's documentation:
The Q_OBJECT macro must appear in the private section of a class definition that declares its own signals and slots or that uses other services provided by Qt's meta-object system.
Example
class MySubClass : public MySuperClass {
Q_OBJECT
public:
MySubClass(quint16 ServerPort, QObject* parent=0);
public slots:
void newValue();
void connectionEstablished();
void disconnected();
};
On the other hand, if you want to connect to a slot in the parent class but implement it in a derived one, then you must make it virtual:
class MySuperclass : public QObject {
Q_OBJECT
// ...
public slots:
virtual void newValue(); // can be virtual pure also
};
class MySubClass : public MySuperClass {
public:
virtual void newValue() override; // overrides parent's
}
Note that there is no need to use the Q_OBJECT macro nor to use the slot: label in the derived class. Slots are normal methods after all. Of course, you have to use it if you add new slots or signals.

A simple subclass of QWidget doesn't work as a QWidget

I create a very simple subclass of QWidget like this:
class WorldView : public QWidget
{
Q_OBJECT
public:
explicit WorldView(QWidget *parent = 0);
signals:
public slots:
};
WorldView::WorldView(QWidget *parent) : QWidget(parent)
{
}
I create an instance of it in main window like this:
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
protected:
virtual void resizeEvent(QResizeEvent* event) override;
private:
WorldView* _worldView;
};
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent)
{
_worldView = new WorldView(this);
_worldView->setStyleSheet(QString("* {background-color : black}"));
}
MainWindow::~MainWindow()
{
delete _worldView;
}
void MainWindow::resizeEvent(QResizeEvent *event)
{
_worldView->resize(size());
}
But the widget does not show as expected.
I have tried to call show(), but it still doesn't show.
The weird thing is that when I replace WorldView with QWidget, the widget shows.
I don't know why.
Because stylesheets don't work that way for custom QWidget subclasses.
From https://doc.qt.io/qt-5/stylesheet-reference.html :
QWidget
Supports only the background, background-clip and background-origin properties.
If you subclass from QWidget, you need to provide a paintEvent for your custom QWidget as below:
void CustomWidget::paintEvent(QPaintEvent *)
{
QStyleOption opt;
opt.init(this);
QPainter p(this);
style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
}
The above code is a no-operation if there is no stylesheet set.
Warning: Make sure you define the Q_OBJECT macro for your custom widget.
(And, in general, stop using stylesheets.)

connect signals on a child widget slot

I have some problems with inheritance in widgets and connecting slots. I have created an abstract Widget which inherits from QWidget. Here is the prototype :
class WidgetParams : public QWidget
{
Q_OBJECT
public:
explicit WidgetParams(QWidget *parent = 0) : QWidget(parent){}
virtual bool paramChanged() = 0;
protected:
bool paramsChanged;
};
Then I created derivated class from WidgetParams, for example WidgetParamsWindows:
class WidgetParamsWindows : public WidgetParams
{
public:
explicit WidgetParamsWindows(QWidget *parent = 0);
virtual bool paramChanged(){return paramsChanged;}
private:
QFormLayout *layout;
QSpinBox *svertical;
QSpinBox *shorizontal;
signals:
public slots:
void changeSomeParam(int value);
};
In WidgetParamsWindows, I have some QSpinBox, QPushButton etc. to adjust the params.
I connect the QSpinBox in WidetParamsWindows like this :
connect(spinbox,SIGNAL(valueChanged(int)),this,SLOT(changeSomeParam(int));
After that, I created a WidgetParamsWindows and put It in a list of WidgetParams, in order to show the correct WidgetParams when the user clicks on it.
But when I tried to change the value in the QSpinBox, nothing change and I have the following message in the console :
QObject::connect: No such slot WidgetParams::changeSomeParam(int)
I don't know why the parent Widget takes the slot, instead of WidgetParamsWindows, do you have any ideas?
There is no Q_OBJECT macro in WidgetParamsWindow, so moc doesn't resolve slot macros, try to add Q_OBJECT in WidgetParamsWindow

Connect: No such Slot QTreeView

I have inherited a class MainTree from QTreeview
maintree.cpp file
void MainTree::LaunchTree()
{
//Tree launching
connect(this, SIGNAL(customContextMenuRequested(const QPoint& )),this,SLOT(showCustomContextMenu(const QPoint&)));
}
void MainTree::showCustomContextMenu(const QPoint &pos)
{
//Add actions
}
But i get the following error
QObject::connect: No such slot QTreeView::showCustomContextMenu(const QPoint&)
I could not understand why, am i missing something ??
Definition of the class MainTree
class MainTree : public QTreeView
{
public:
MainTree();
MainTree(QWidget *parent = 0);
public slots:
private slots:
void showCustomContextMenu(const QPoint& pos);
private:
void launchTree();
};
You are missing the Q_OBJECT macro out, so try this:
class MainTree : public QTreeView
{
Q_OBJECT
// ^^^^^
public:
MainTree();
MainTree(QWidget *parent = 0);
public slots:
private slots:
void showCustomContextMenu(const QPoint& pos);
private:
void launchTree();
};
Do not forget to re-run qmake after this to regenerate the moc files properly. Make sure you have the moc include at the end of your source code, or you handle the moc generation without that.
Also, note that if you used Qt 5.2 or later with C++11 support, you would get a static assertion about the missing Q_OBJECT macro, so you would not get runtime issues anymore. I suggest to follow that if you can.
When referring to slot and signals you have to omnit all decoration: const & and so on (only star can remain).
connect(this, SIGNAL(customContextMenuRequested(QPoint)),
this, SLOT(showCustomContextMenu(QPoint)))
Also you forgot about Q_OBJECT macro.