Kitty Burner
Kitty Burner

Reputation: 47

Initializing a Ui pointer From a QMainWindow class to a QDialog Class

I'm really stuck on one problem that I want to solve. the problem is that I have a Class for QMainWindow which holds the Ui variable for that form. Now I want to be able to edit that Form using the Ui variable in that class on a QDialog cpp file. I probably sound really stupid and I really have no idea how I should explain this, but I have code which maybe can help.

MainWindow.h:

#include "ui_mainwindow.h"
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT

public:   
explicit MainWindow(QWidget *parent = 0);


~MainWindow();
protected:
    Ui::MainWindow *ui;
}

MainWindow.cpp:

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "dialog.h"
Dialog *dialog;

MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}

MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pushButton_clicked()
{
dialog = new Dialog(this); 
dialog->show();
}

QDialog.cpp:

#include "ui_mainwindow.h"
#include "mainwindow.h"
#include "dialog.h"
#include "ui_dialog.h"

Dialog::Dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog)
{
ui->setupUi(this);
}

Dialog::~Dialog()
{
delete ui;
}

Ui::MainWindow *mainui;
void Dialog::on_pushbutton_clicked(){
mainui->label->setText("test");
}

So as you can see from the above code, it shows that I have a pointer to the Ui variable however its uninitialised, therefore it would lead to a SIGSEGV error, so how to do Initialize this pointer? any help here is highly appreciated, and even though this is probably really simple I just don't know what to do. (I have looked at other questions but I couldn't quite grasp what to do, so please explain what I am to do before linking me to a similar question. Also, I have left out the Dialog.h file as I didn't think it was needed, please tell me if I need to show it, thanks!).

Upvotes: 3

Views: 1658

Answers (2)

docsteer
docsteer

Reputation: 2516

Generally in C++ you should practice what is called encapsulation - keep data inside a class hidden from others that don't need to know about it. It's not good to have multiple pointers to the UI object as now all those other objects have to know how the main window UI is implemented.

In this case, what I would recommend is to use Qt's signals and slots mechanism to allow the dialog to tell the main window what you need it to do. That has the advantage that if you add more dialogs, or change how things are implemented in the main window, you don't need to alter the signal slot mechanism, and the details are hidden cleanly.

So - for your dialog, add a signal like this in the header file

class Dialog : QDialog
{
   Q_OBJECT
   signals:
      void setTextSignal(QString text);
}

and in your main window header, add a slot.

class MainWindow : public QMainWindow
{
  Q_OBJECT
public slots:
   void setTextSlot(const QString &text);
}

now in your method where the button is pressed,

void Dialog::on_pushbutton_clicked()
{
   emit setTextSignal("test");
}

and in your main window

void MainWindow::setTextSlot(const QString &text)
{
   mainUi->label->setText(text);
}

The final part is to connect the signal and slot together, which you would do in your main window function where you create the dialog:

void MainWindow::on_pushButton_clicked()
{
   dialog = new Dialog(this); 
   connect(dialog, SIGNAL(setTextSignal(QString)), this, SLOT(setTextSlot(QString)));
   dialog->show();
}

You can see there are many advantages to this; the Dialog no longer needs a pointer to the main window UI, and it makes your code much more flexible (you can have other objects connected to the signals and slots as well).

Upvotes: 1

Felix
Felix

Reputation: 7146

Short answere - your can't! If you want to create a new instance of the ui, you would have to do:

MainWindow::Ui *ui = new MainWindow::UI();
ui->setupUi(this);

However, the this-pointer for a UI created for a QMainWindow based class must inherit QMainWindow - thus, you can't.

In general, it is possible if you create your Ui based on a QWidget instead of a QMainWindow, since both inherit QWidget.

Alternativly, you could try the following:

QMainWindow *subWindow = new QMainWindow(this);
subWindow->setWindowFlags(Qt::Widget);
MainWindow::Ui *ui = new MainWindow::UI();
ui->setupUi(subWindow );
//... add the mainwindow as a widget to some layout

But I would guess the result will look weird and may not even work in the first place.

Upvotes: 0

Related Questions