[Solved] How to cast my NewClass:Qwidget to QWidget in constructor?
-
I have got this implementation:
mainwindow.h:
@
class MainWindow : public QMainWindow
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
[...]
private:
Ui::MainWindow *ui;
SubWindow *subWindow;
@subwindow.h:
@
class SubWindow : public QMainWindow
{
public:
explicit SubWindow(MainWindow *_caller, QWidget *parent = 0);
//explicit SubWindow(QWidget *parent = 0);
~SubWindow();
[...]
private:
Ui::SubWindow *ui;
MainWindow *caller;
};
@The idea is to have 2 linked windows: MainWindow and SubWindow; the former is the parent one, the last is the child one. MainWindow has subwindow variable: SubWindow. And viceversa, SubWindow has caller variable, pointing to MainWindow.
I open the new window this way:
@
void MainWindow::openSubWindow()
{
subWindow = new SubWindow(this, this);
subWindow->show();ui->ButtonNewWindow->setEnabled(false);
}
@And SubWindow saves the MainWindow in constructor this way:
@
SubWindow::SubWindow(MainWindow *_caller, QWidget *parent) : QMainWindow(parent), ui(new Ui::SubWindow)
{
ui->setupUi(this);caller = _caller;
}
@The goal is to get the reference to MainWindow in the constructor. This is done, but...
I think this code is awful!! I need to use "new SubWindow(this, this);" in order to accomplish the objective of getting the caller and make the right calls to base constructors. I think this should be: "new SubWindow(this)", but all the SubWindow constructor variations I've tried make the compiler complaining.
Examples:
SubWindow::SubWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::SubWindow) -> Error in "caller = _caller;"
SubWindow::SubWindow(MainWindow *parent) : QMainWindow(parent), ui(new Ui::SubWindow) -> error
SubWindow::SubWindow(MainWindow *parent) : QMainWindow((QWidget *)parent), ui(new Ui::SubWindow) -> error
etc...
I know this is probably a dummy's question, but I've made the effort of reading doc about C++ classes, derived classes, downcasting and upcasting, and I don't get the spot.
So, How should I have performed this?
-
First of all you will probably soon want to use custom signals/slots in your classes so you should include Q_OBJECT macro in your declarations:
@
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
...
@You can go then with SubWindow::SubWindow( QWidget parent ) and use a cast to store the caller:
@
caller = qobject_cast<QMainWindow>(parent);
@but to be honest this design of storing each others pointers is not that good and can become problematic to maintain with large number of objects in a long run. Qt has this quite great notion of object connections so you don't have to pass stuff around everywhere. Sometimes it's useful of course so I'm not saying never to do it, but with Qt it's often good thing to reconsider your design.
"Here's":http://qt-project.org/doc/qt-5.0/qtcore/qobject.html#connect the documentation for connect.
As an example:
@
SomeCustomWidget* w1 = new SomeCustomWidget();
QWidget* w2 = new QWidget();QObject::connect(w1->someButton, &QPushButton::clicked, w2, &QWidget::show );
@This way, when a button is clicked inside the first widget second one will be shown. With custom signals and slots you can do this for virtually all your communication between widgets, and none of them has to have any knowledge about the others. One just signals some state change and other executes some slot when it receives the signal. You can control visibility, object destruction, state changes etc. and pass the state change description or options as signal parameters.
-
2 responses in one, great!
Don't worry, the two classes I posted have Q_OBJECT clause. I hide it in order to raise briefness and clearance.
I've understand what you meant with the signal-slot solution you proposed. The idea I had was based in other programming ambiances; but thinking about you said makes it logical.
Great point, Krzysztof Kawa!!