2016-03-02 5 views
2

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

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"); 
} 

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

+0

Добро пожаловать в SO. Здесь, чтобы отметить ответ, который вам нужен, вам просто нужно использовать небольшую зеленую метку (как и вы) на правильный ответ. Нет необходимости редактировать вопрос и/или заголовок. –

+0

Ой хорошо, не знал этого (И ты уже знаешь, что я новичок в SO: p) Спасибо. –

ответ

1

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

В этом случае я бы рекомендовал использовать механизм сигналов и слотов 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(); 
} 

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

+0

Отлично, это именно то, что я хочу, большое спасибо !!!! –

0

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

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

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

В целом, это возможно, если вы создали свой Ui на основе QWidget вместо QMainWindow, так как оба наследуют QWidget.

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

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 

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

+0

Спасибо за ваш ответ, но кто-то пришел вместе с идеями и слотами, что мне и нужно. –

+0

А, кажется, я неправильно понял ваш вопрос;) Я думал, что вы хотите создать второй – Felix

Смежные вопросы