Qt - What do we mean by those code snippets - c++

I just have those questions about those code sinppets from the C++ GUI Programming with Qt 4 book:
GoToCellDialog::GoToCellDialog(QWidget *parent):QDialog(parent)
Does that mean we are inheriting QDialog(parent)? Or, what exactly does this mean?
setupUi(this);
Here, this code snippet is part of the gotocelldialog.cpp file, which is the implementation of gotocelldialog.h header file. What do we mean by this in this context? What are we trying to setup? And, what kind of setup will that be?
Thanks.

GoToCellDialog::GoToCellDialog(QWidget *parent) : QDialog(parent)
: signifies an initializer list. And it meant, parent is being passed as a parameter to QDialog constructor. I assume GoToCellDialog is derived from QDialog and so sending parent to it's constructor. So, before even body of GoToCellDialog is executed, QDialog constructor is executed.
This example should give you an idea -
class foo
{
int number ;
public:
foo(int i) : number(i) // Means copying value of i to number
{}
};
class bar : public foo
{
public:
bar(int temp) : foo(temp)
{ // <- Before getting here, foo sub object must be constructed.
// Because the order of construction takes from parent to child.
}
};
In the above example, definitely an argument for foo constructor must be passed while instantiation of bar. So, initializer list is the only way because there is no default constructor( i.e., constructor with no arguments) available for foo.

To answer your questions:
Does that mean we are inheriting QDialog(parent)?
Yes, this is basic C++ inheritance.
setupUi(this);
In short: The 'User Interface compiler' (uic) compiles/translates the xml file to C++ code which will be compiled and linked. The setupUi() function ensures that the Qt designer widgets you made (generated C++ code) are setup to be used by your code by Building the Widget tree.

Related

How to make Qt Signal emit by value without compile errors instead of reference?

I read that the signal/slot concept in qt should always pass arguments by value instead of reference to ensure that signals/slots work flawlessly between threads.
I now have a piece of code that will only compile when the argument to a signal is emitted by reference, not value:
#include <QObject>
class mythirdclass {
public:
mythirdclass();
};
class mysecondclass : public QObject, public mythirdclass {
public:
mysecondclass(mythirdclass third);
};
class myclass : public QObject {
Q_OBJECT
public:
myclass();
signals:
// not working
void messageReceived(mysecondclass mymessage);
// working
// void messageReceived(mysecondclass &mymessage);
};
myclass::myclass()
{
mythirdclass third;
mysecondclass msg(third);
emit messageReceived(msg);
}
mysecondclass::mysecondclass(mythirdclass third)
{
// DO stuff
}
mythirdclass::mythirdclass()
{
}
The compiler error is:
..\example\main.cpp: In constructor 'myclass::myclass()':
..\example\main.cpp:28:20: error: use of deleted function 'mysecondclass::mysecondclass(const mysecondclass&)'
emit signal(second);
^
..\example\main.cpp:8:7: note: 'mysecondclass::mysecondclass(const mysecondclass&)' is implicitly deleted because the default definition would be ill-formed:
class mysecondclass : QObject, public mythirdclass {
^
Based on the errors I thought abour writing a copy constructor for mysecondclass, however after some attempts I gave up for now, because I didn't get it right.
So my questions are:
why is the compiling failing in the first place?
if it fails because of a missing copy constructor, why is the compiler not able to define one implicitly?
how would the working copy constructor in my case look like?
Thanks in advance.
Why is the compiling failing in the first place?
Because passing by value implies copying, and if the copy-constructor is deleted, then it simply can't pass by value and your function cannot be compiled with this signature, while it can receive its argument by reference because it doesn't involve copying.
If it fails because of a missing copy constructor, why is the compiler not able to define one implicitly?
It actually fails because it hasn't been able to define one implicitly. The reason for that is that your class derives from QObject. And that QObject doesn't have a public or protected copy-constructor, by design. So the compiler cannot define one implicitly.
How would the working copy constructor in my case look like?
Given the nature of QObjects, and the design decision that's behind it when it comes to QObjects not being copyable, I would recommend against using signals and slots that take QObjects or class deriving from it by value (or simply any function that does this, and signals/slots are mainly functions deep down), but instead by reference or by pointer.
For you third question, if you do not want to define a default constructor for mysecondclass, your copy constructor would probably look like
mysecondclass(mysecondclass const &other) : mythirdclass() {
/// stuff
}
For your second question, I suppose (not sure) that the default copy constructor try to use the default constructor that has been automatically deleted because you have defined another constructor of mysecondclass from an object of mythirdclass (I would recommend to you to use a const reference for the parameter here to avoid a useless copy)

Why QObject needs to be the first in case of multiple inheritance

According to http://qt-project.org/doc/qt-4.8/moc.html#multiple-inheritance-requires-qobject-to-be-first the QObject must be the first in the base classes when using multiple inheritance.
Is this because of some limitation in the moc tool or C++ memory layout problems are taken into consideration too, thus this restriction came into existence?
Assume that we have a class Test declared as:
class Test : public Foo, public QObject
{
Q_OBJECT
[..]
};
If you take a look at the moc_test.cpp file that the moc tool has generated, you will see something like:
[..]
const QMetaObject Command::staticMetaObject = {
{ &Foo::staticMetaObject, qt_meta_stringdata_Command,
qt_meta_data_Command, &staticMetaObjectExtraData }
};
[..]
Compiler will complain about staticMetaObject not being the member of Foo, as Foo is not a QObject. For some reason the moc tool generates this code taking the first parent class. Thus if you declare Test as:
class Test : public QObject, public Foo {};
The generated code will look fine to compiler.
I think this is made just for convenience because moc tool will hardly know which of the parent classes is a QObject without parsing the whole hierarchy.
Note: If you don't use the Q_OBJECT macro, you can derive your class from others in any order.

Getting the name of sub class within super class in Qt

I have a base class that is inherited by two sub classes. All three classes use qDebug() to do some debug printing and Q_FUNC_INFO to identify the source of the print. The problem is that when printing from the base class, Q_FUNC_INFO contains the name of the base class, making it impossible to know which of the two sub classes the instance represents.
The best solution I have come up with so far is using a QString variable instead of Q_FUNC_INFO at the base class and supplying it with the correct name when instantiating.
Are there any other, more preferable solutions?
Are there any other, more preferable solutions?
In general, no, that is fine. In such cases, you would need to place the Q_FUNC_INFO into the subclass if that is possible. If not, you are out of luck, but... please read on.
Qt internally also uses explicit strings rather than Q_FUNC_INFO, I believe partially for this reason.
For QObjects, you could use the meta object compiler for some introspection to get the real name dynamically, namely:
const char * QMetaObject::className() const
Returns the class name.
and
const QMetaObject * QObject::metaObject() const [virtual]
Returns a pointer to the meta-object of this object.
A meta-object contains information about a class that inherits QObject, e.g. class name, superclass name, properties, signals and slots. Every QObject subclass that contains the Q_OBJECT macro will have a meta-object.
The meta-object information is required by the signal/slot connection mechanism and the property system. The inherits() function also makes use of the meta-object.
If you have no pointer to an actual object instance but still want to access the meta-object of a class, you can use staticMetaObject.
You also take a look into this when dealing with constructors as your comment seems to indicate it:
QMetaMethod QMetaObject::constructor(int index) const
Returns the meta-data for the constructor with the given index.
main.cpp
#include <QObject>
#include <QDebug>
class Foo : public QObject
{
Q_OBJECT
public:
virtual void baz() { qDebug() << "Class name:" << metaObject()->className(); }
};
class Bar : public Foo
{
Q_OBJECT
};
#include "main.moc"
int main()
{
Bar bar;
bar.baz();
return 0;
}
Output
moc main.cpp -o main.moc && g++ -Wall -I/usr/include/qt -I/usr/include/ -I/usr/include/qt/QtCore -lQt5Core -fPIC main.cpp && ./a.out
Class name: Bar
Note: if you would like to get this mechanism work in the constructor, the simple answer is that you cannot. Nothing will really help you there. That is due to the fact how inheritance is handled in C++. First, the base class is constructed, and at that stage, the subclass is yet fully constructed (strictly speaking, not even the base), so you cannot really get more information about it without explicitly making sure with an additional argument to the base class constructor. But then, you would get a bloated API just for this simple thing. I would suggest in such a case to just put the print into the subclasses as opposed to the base classes.

class constructor initialization?

I am trying to understand the following code.(I am learning C++)
class DefaultDevice : public Device {
public:
DefaultDevice() :
ui(new DefaultUI) {
}
private:
RecoveryUI* ui;
};
class DefaultUI : public ScreenRecoveryUI {
...
}
I am having little trouble understanding ui(new DefaultUI) part.
As I understand it is part of initialization before DefaultDevice() constructor is executed.
Then, from my understanding, it is going to call ReocoveryUI constructor with new DefaultUI argument. But, RecoveryUI class does not have any constructor with such argument.(sorry for not posing RecoveryUI class. it's too long :( if anyone interested in, it is Android Open source code)
so what does this 'new DefaultUI' do?
If that is a valid and working code, It seems RecoveryUI is a base class for DefaultUI.
ui(new DefaultUI) creates an object and assigns it to ui.
So, ui points to its child object.
It is not run before the ctor, it is part of the ctor. It's called an initializer list and it's used to initialize the (non-static) member variables of a class.

Qt "no matching function for call"

I have
no matching function for call to 'saveLine::saveLine()'
error when compiling my application. The construcor is never actually called.
saveLine class definition:
class saveLine
{
public:
saveLine(QWidget *parent);
private:
QPushButton *selectButton, *acceptButton;
QLabel *filePath;
QLineEdit *allias;
};
saveLine is used in another class which is defined as follows:
class MWindow : public QWidget
{
Q_OBJECT
public:
MWindow(QWidget *parent=0);
private:
saveLine line1;
};
error points to MWindow constructor implementation
MWindow::MWindow(QWidget *parent):QWidget(parent)
{
this->setWindowTitle("Launcher");
this->resize(600,600);
}
What should i do? I intend to use saveLine class in a vector, to create lines at runtime.
EDIT: i've misdeclared line1, it should read
saveLine *line1;
but now it gives another error
ISO C++ forbids declaration of 'saveLine' with no type
and
expected ';' before '*' token
on this line. It seems like saveLine is no longer considered a class, how so?
Since you provide a user-declared constructor for the class saveLine, the default constructor is not provided by the compiler. Your constructor is not a default constructor (it has one required parameter), so you cannot default construct an object of type saveLine.
Since you have a saveLine object in your MWindow class, you need to initialize it using your constructor, in the MWindow constructor's initializer list:
MWindow::MWindow(QWidget *parent)
: QWidget(parent), line1(parent)
{
//...
}
(I'm assuming that parent pointer is the one you mean to pass; if you need to give it something else, then give it what it needs)
Another option would be to provide a default argument for the parameter in saveLine's constructor:
saveLine(QWidget *parent = 0);
This would allow that constructor to be called with no arguments (and would make it a default constructor). Whether this makes sense to do depends on whether the parent pointer really is optional. Obviously, if you do this, you'll need to check to be sure the pointer is not null before you dereference and use it.
but now it gives another error
ISO C++ forbids declaration of
'saveLine' with no type
You need to add a forward declaration to tell the compiler that saveLine class exists:
Like this:
//declare that there will be a class saveLine
class saveLine;
class MWindow : public QWidget
{
Q_OBJECT
public:
MWindow(QWidget *parent=0);
private:
saveLine *line1;
};
You have to call the constructor of saveLine in the constructor of MWindow giving him the desired parent.
Use:
MWindow::MWindow(QWidget *parent) : QWidget(parent), line1(parent)
{
this->setWindowTitle("Launcher");
this->resize(600,600);
}
You are declaring an instance of saveLine in the class declaration, instead of a pointer to a saveLine.
You could change the reference in MWindow to
saveLine* line1;
OR
you could implement like this:
MWindow::MWindow(QWidget *parent):QWidget(parent), line1(parent)
{
this->setWindowTitle("Launcher");
this->resize(600,600);
}
Try adding class saveLine; just above the class MWindow line. This often occurs when the .h files for the saveLine class and the MWindow class include each other (either directly or indirectly). For example, see the first few posts of http://www.allegro.cc/forums/thread/594307