Инициализация указателя пользовательского интерфейса из класса QMainWindow в класс QDialog


Я действительно застрял на одной проблеме, которую хочу решить. проблема в том, что у меня есть класс для QMainWindow, который содержит переменную Ui для этой формы. Теперь я хочу иметь возможность редактировать эту форму, используя переменную Ui В этом классе в файле qdialog cpp. Наверное, это звучит очень глупо, и я действительно не знаю, как мне это объяснить, но у меня есть код, который, возможно, может помочь.

Главное окно.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;
}

Главное окно.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");
}

Так как вы как видно из приведенного выше кода, он показывает, что у меня есть указатель на переменную Ui, однако он неинициализирован, поэтому это приведет к ошибке SIGSEGV, так как же инициализировать этот указатель? любая помощь здесь высоко ценится, и хотя это, вероятно, действительно просто, я просто не знаю, что делать. (Я рассматривал другие вопросы, но не мог понять, что делать, поэтому, пожалуйста, объясните, что я должен делать, прежде чем связывать меня с аналогичным вопросом. Кроме того, я пропустил Диалог.H файл как я не думал, что это нужно, пожалуйста, скажите мне, если мне нужно показать его, Спасибо!).

2 2

2 ответа:

Обычно в C++ вы должны практиковать то, что называется инкапсуляцией - хранить данные внутри класса, скрытые от других, которым не нужно об этом знать. Нехорошо иметь несколько указателей на объект UI, так как теперь все эти другие объекты должны знать, как реализован интерфейс главного окна.

В этом случае я бы рекомендовал использовать механизм сигналов и слотов Qt, чтобы позволить диалогу сообщить главному окну, что вам нужно сделать. Это имеет то преимущество, что если вы добавите больше диалоги, или изменить то, как вещи реализованы в главном окне, вам не нужно изменять механизм слота сигнала, и детали скрыты чисто.

Итак-для вашего диалога добавьте такой сигнал в заголовочный файл

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

И в заголовке главного окна добавьте слот.

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

Теперь в вашем методе, где кнопка нажата,

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

И в главном окне

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

Заключительная часть состоит в том, чтобы соединить сигнал и слот вместе, что вы бы сделали в функция главного окна, в которой вы создаете диалог:

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

Вы видите, что в этом есть много преимуществ; диалог больше не нуждается в указателе на интерфейс главного окна, и это делает ваш код гораздо более гибким (вы можете иметь другие объекты, подключенные к сигналам и слотам).

Короткий ответ-ваш не может! Если вы хотите создать новый экземпляр пользовательского интерфейса, вам придется сделать:

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

Однако this-указатель для пользовательского интерфейса, созданного для класса на основе QMainWindow, должен наследовать QMainWindow - таким образом, вы не можете.

В общем случае это возможно, если вы создадите свой пользовательский интерфейс на основе QWidget вместо QMainWindow, так как оба наследуют QWidget.

Альтернативно, вы можете попробовать следующее:

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

Но я бы предположил, что результат будет выглядеть странно и может даже не работать в первое место.