Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > С/С++: Кроссплатформенное программирование, Qt/Gtk+/wxWidgets > [Qt 4.5] добавить формы в QStackedLayout


Автор: IKM2007 7.3.2010, 21:29
Как добавить несколько форм в QStackedLayout без создания для каждого из них наследуемого класса(то есть использовав только сгенерированные uic классы)?

Автор: borisbn 7.3.2010, 22:34
А чем http://qt.nokia.com/doc/4.6/qstackedlayout.html#addWidget не подходит?

Автор: andrew_121 7.3.2010, 22:54
borisbn, ну добавлять придется именно таким макаром.

IKM2007, вообще, можно. только не понимаю пользы от таких форм. реализации у них нет же. они ничего, кроме как отображаться, не могут.

Автор: SABROG 8.3.2010, 02:53
Цитата(IKM2007 @  7.3.2010,  21:29 Найти цитируемый пост)
то есть использовав только сгенерированные uic классы

Я не понял. Ты хочешь в дизайнере сделать 10 виджетов и потом их добавить в QStackeLayout или наоборот не использовать дизайнер вообще, а все создать в рантайме и потом добавить?

Автор: IKM2007 8.3.2010, 08:16
Цитата(SABROG @  8.3.2010,  02:53 Найти цитируемый пост)
Я не понял. Ты хочешь в дизайнере сделать 10 виджетов и потом их добавить в QStackeLayout или наоборот не использовать дизайнер вообще, а все создать в рантайме и потом добавить? 

Нет, речь не о динамических страницах. Создал форму, во время создания выбрал widget. Теперь не знаю где этот виджет и как ее имя. Попробовал так:

Код

stackedLayout->addWidget(Ui::MainForm);
stackedLayout->addWidget(Ui::GameMenuForm);


не получилось.

Автор: SABROG 8.3.2010, 13:20
В .cpp файле (например в mainwindow.cpp) подключаешь все хедеры новых форм:

Код

#include "widget1.h"
#include "widget2.h"
#include "widget3.h"


И затем создаешь экземпляры:

Код

Widget1* widget1 = new Widget1(this);
Widget2* widget2 = new Widget2(this);
Widget3* widget3 = new Widget3(this);

stackedLayout->addWidget(widget1);
stackedLayout->addWidget(widget2);
stackedLayout->addWidget(widget3);


Указатели можно сохранить в private секции класса главного окна, чтобы потом можно было легко достучаться до этих виджетов.

Автор: IKM2007 8.3.2010, 18:01
SABROG, делаю так:


Код

Ui::MainForm *mainFormWgt = new Ui::MainForm(this);
Ui::GameMenuForm *gameMenuFormWgt = new Ui::GameMenuForm(this);

stackedLayout->addWidget(mainFormWgt);
stackedLayout->addWidget(gameMenuFormWgt);


такие ошибки:
Код

E:/QTProjects/CourseWork__2/main_window.cpp:21: error: no matching function for call to `Ui_MainForm::Ui_MainForm(MainWindow* const)'

E:/QTProjects/CourseWork__2/main_window.cpp:22: error: no matching function for call to `Ui_GameMenuForm::Ui_GameMenuForm(MainWindow* const)'

E:/QTProjects/CourseWork__2/main_window.cpp:24: error: no matching function for call to `QStackedLayout::addWidget(Ui_MainForm*&)'

E:/QTProjects/CourseWork__2/main_window.cpp:25: error: no matching function for call to `QStackedLayout::addWidget(Ui_GameMenuForm*&)'


На всякий случай выложу .h и .cpp файлы.
main_window.h
Код

#ifndef MAIN_WINDOW_H
#define MAIN_WINDOW_H


#include <QDialog>
#include <QStackedLayout>
#include "ui_Main_form.h"
#include "ui_GameMenu_form.h"

class MainWindow : public QWidget, public Ui::MainForm, public Ui::GameMenuForm
{
    Q_OBJECT
public:
    MainWindow(QWidget *pwgt = 0);

private slots:
    void ClickedGame();
    void ClickedOptions();
    void ClickedSinglePlayer();
    void ClickedOnline();
    void ClickedMainMenu();

private:
    QStackedLayout* stackedLayout;

};
#endif // MAIN_WINDOW_H



main_window.cpp
Код


#include <QtGui>

#include "main_window.h"
MainWindow::MainWindow(QWidget *pwgt) : QWidget(pwgt)
{
Ui_MainForm::setupUi(this);
Ui_GameMenuForm::setupUi(this);
connect(game_button, SIGNAL(clicked()), this, SLOT(ClickedGame()));
connect(options_button, SIGNAL(clicked()), this, SLOT(ClickedOptions()));
connect(quit_button, SIGNAL(clicked()), this, SLOT(reject()));
connect(single_player_button, SIGNAL(clicked()), this, SLOT(ClickedSinglePlayer()));
connect(online_button, SIGNAL(clicked()), this, SLOT(ClickedOnline()));
connect(main_menu_button, SIGNAL(clicked()), this, SLOT(ClickedMainMenu()));

stackedLayout = new QStackedLayout(this);


Ui::MainForm *mainFormWgt = new Ui::MainForm(this);
Ui::GameMenuForm *gameMenuFormWgt = new Ui::GameMenuForm(this);
stackedLayout->addWidget(mainFormWgt);
stackedLayout->addWidget(gameMenuFormWgt);
stackedLayout->setCurrentIndex(0);
}

void MainWindow::ClickedGame()
{
stackedLayout->setCurrentIndex(1);

}

void MainWindow::ClickedOptions()
{

}


void MainWindow::ClickedSinglePlayer()
{

}

void MainWindow::ClickedOnline()
{

}

void MainWindow::ClickedMainMenu()
{

}


Автор: SABROG 8.3.2010, 19:28
Вот ты навертел то:

Код

class MainWindow : public QWidget, public Ui::MainForm, public Ui::GameMenuForm


Классы Ui::MainForm и тому подобные не являются виджетами. Это обычные классы, которые наследуют классы типа Ui_MyClass, которые в свою очередь не наследуют виджетов. В них находятся только списки указателей на дочерние виджеты и методы типа setupUi(), который создает дочерние виджеты и ставит им того родителя, которого ты передал в метод setupUi().

Тебе нужно сделать по аналогии с MainWindow:

//page1.h
Код

#ifndef PAGE1_H
#define PAGE1_H

#include <QtCore/QScopedPointer>
#include <QtGui/QWidget>

namespace Ui {
    class Page1;
}

class Page1 : public QWidget {
    Q_OBJECT
public:
    Page1(QWidget *parent = 0);
    ~Page1();

private:
    QScopedPointer<Ui::Page1> ui;
};

#endif // PAGE1_H


//page1.cpp
Код

#include "page1.h"
#include "ui_page1.h"

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

Page1::~Page1()
{
}


И так для каждой страницы. Я не знаю в какой среде ты пишешь, но QtCreator генерит их автоматически, если .ui файл создается через контекстное меню "Добавить Новый->Класс Формы Qt Designer"

Автор: IKM2007 8.3.2010, 20:28
Цитата(SABROG @  8.3.2010,  19:28 Найти цитируемый пост)
но QtCreator генерит их автоматически, если .ui файл создается через контекстное меню "Добавить Новый->Класс Формы Qt Designer"

Я так и сделал, то есть получается, что сперва создаем форму, затем создаем для каждой из форм свой отдельный класс наследующий сгенерированный класс соответствующей формы и только эти классы можем использовать, как виджеты?

Автор: SABROG 8.3.2010, 20:51
Цитата(IKM2007 @ 8.3.2010,  20:28)
Цитата(SABROG @  8.3.2010,  19:28 Найти цитируемый пост)
но QtCreator генерит их автоматически, если .ui файл создается через контекстное меню "Добавить Новый->Класс Формы Qt Designer"

Я так и сделал, то есть получается, что сперва создаем форму, затем создаем для каждой из форм свой отдельный класс наследующий сгенерированный класс соответствующей формы и только эти классы можем использовать, как виджеты?

Да.
Форма остается формой, пока её не заполнишь каким-нибудь расплавленным металлом. И тогда уже называть свой виджет Form::Form - не правильно, это уже готовый продукт и называть его следует MyWidget или как угодно, но только не Form.

Автор: IKM2007 9.3.2010, 09:19
SABROG, я сделал не так, как сделал ты, у меня была ошибка, компилятор не мог найти <QtCore/QScopedPointer>, в общем сделал так:

.h
Код

#ifndef PAGE1_H
#define PAGE1_H

#include <QtGui/QWidget>

#include "ui_form.h"

class Page1:public QWidget, public Ui::Form
{
Q_OBJECT

    public:
    Page1(QWidget *parent = 0);

};

#endif // PAGE1_H


.cpp
Код

#include "page1.h"

Page1::Page1(QWidget *parent) :
    QWidget(parent)
{
    Ui::Form::setupUi(this);
}


Спасибо за помощь. smile 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)