Russian Qt Forum

Qt => Пользовательский интерфейс (GUI) => Тема начата: jerdeks от Март 23, 2010, 10:16



Название: управление окнами MDI
Отправлено: jerdeks от Март 23, 2010, 10:16
такой вопрос. можно ли из subwindow управлять главной формой? например, по какому-то событию в subwindow выводить инфу в statusbar,  который в главном окне?

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


Название: Re: управление окнами MDI
Отправлено: voronElf от Март 23, 2010, 10:35
можно конечно. в форме которая обращается дожен быть адрес той формы, к которой обращаются. Ну или этот адрес можно получать откуда-нибудь (например из каркаса приложения, если предусмотрен в архитектуре).
Хедеры можно подключать в файлах реализации.
Или при разработке структуры проекта продумывать подрядок подключения хедеров. У меня например главное окно о суб-окнах не знает ничего (хедеры соотв. не подключаются), просто предоставляет интерфейс для добавления субокна, зато все модули о главном окне знают (подключают хедеры каркаса) и могут его адрес получить из каркаса.


Название: Re: управление окнами MDI
Отправлено: alexman от Март 23, 2010, 10:36
1. Можно использовать сигналы/слоты.
2. Подключай файлы в cpp, а в h-файлах храни указатели.


Название: Re: управление окнами MDI
Отправлено: developer от Март 23, 2010, 11:20
Я бы сделал так

Сначала сохранил бы все формы в QMap* map - где ключ ето имя формы а значение - объект формы.  Ету структуру я б сохранил именно в классе главного окна, и заполнил ее нужными формами при конструировании главного окна. Причем класс каждой формы должен иметь указатель на главную форму.


Название: Re: управление окнами MDI
Отправлено: lit-uriy от Март 23, 2010, 12:47
>>как вообще из одной формы обращаться к элементам другой
тема тут неоднократно поднималась, ищите.


Название: Re: управление окнами MDI
Отправлено: jerdeks от Март 23, 2010, 18:35
в форме которая обращается дожен быть адрес той формы, к которой обращаются.
а как это - должен быть адрес? ну теоретически-то понятно, но как это реально сделать?
главное окно о суб-окнах не знает ничего (хедеры соотв. не подключаются), просто предоставляет интерфейс для добавления субокна, зато все модули о главном окне знают (подключают хедеры каркаса) и могут его адрес получить из каркаса.
но ведь суб окна должны появляться по событиям главного окна, а оно оних ничего не знает. как их вызвать?

Я бы сделал так

Сначала сохранил бы все формы в QMap* map - где ключ ето имя формы а значение - объект формы.  Ету структуру я б сохранил именно в классе главного окна, и заполнил ее нужными формами при конструировании главного окна. Причем класс каждой формы должен иметь указатель на главную форму.
крута, но я не понял( может быть какой-нить пример есть?


Название: Re: управление окнами MDI
Отправлено: jerdeks от Март 23, 2010, 18:36
>>как вообще из одной формы обращаться к элементам другой
тема тут неоднократно поднималась, ищите.

спасибо


Название: Re: управление окнами MDI
Отправлено: jerdeks от Март 23, 2010, 21:06
2. Подключай файлы в cpp, а в h-файлах храни указатели.
а это как? объясни пожалуйста


Название: Re: управление окнами MDI
Отправлено: alexman от Март 23, 2010, 21:10
a.h
Код:
class B;
class A
{
...
B* b;
};

a.cpp
Код:
#include "b.h"
...

b.h
Код:
class A;
class B
{
...
A* a;
};

b.cpp
Код:
#include "a.h"
...


Название: Re: управление окнами MDI
Отправлено: developer от Март 24, 2010, 00:38
Примерчик.


Название: Re: управление окнами MDI
Отправлено: developer от Март 24, 2010, 00:40
Если что-то непонятно - обращайся. ПРимер нормально компилиться. Может поможет


Название: Re: управление окнами MDI
Отправлено: voronElf от Март 24, 2010, 06:30
Цитировать
а как это - должен быть адрес? ну теоретически-то понятно, но как это реально сделать?
внутренняя переменная класса, как у alexman в примере кода.

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


Название: Re: управление окнами MDI
Отправлено: jerdeks от Март 24, 2010, 18:00
Примерчик.
спасибо. так тоже интересно, но я с мди хочу.

внутренняя переменная класса, как у alexman в примере кода.

сделал, компилица, крута. но к элементам главной формы все равно не обратиться. подключил в субформе ui_mainwondow.h, тогда доступ к её уи есть, все компилица, но вылетает с ошибкой секгментации


Название: Re: управление окнами MDI
Отправлено: jerdeks от Март 24, 2010, 18:04
главное окно о своих событиях отсылает сигналы и все. Что происходит по реакции на эти сигналы - оно не знает. А в слотах может быть что угодно, в том числе и создание субокон.

я правильно понимаю: слоты это процедуры, которые обрабатывают сигналы? если да, то в какой форме описывать слоты? и как сигналы будут ловиться? и где connect(...) писать?

извините уж за ламерство, в дельфи такого не было)))


Название: Re: управление окнами MDI
Отправлено: voronElf от Март 25, 2010, 08:32
Цитировать
но к элементам главной формы все равно не обратиться
эт смотря как ты подключил ui в свою форму, если ui в private засунул, то конечно не обратишься из другого класса.

как описывать слоты это в документацию (как обычные методы класса, только в разделе public slots:)

connect нужно делать там, где известны адреса обоих объектов, учавствующих в коннекте (в одной из форм можно делать, которая знает о другой форме)

если законекчено, то в ответ на сигнал вызывается соответствующий слот. Подробнее механизм опять же в доках. Кажется в книжке Бланшета (или у Шлее) описано все это было...


Название: Re: управление окнами MDI
Отправлено: jerdeks от Март 25, 2010, 10:56
Цитировать
но к элементам главной формы все равно не обратиться
эт смотря как ты подключил ui в свою форму, если ui в private засунул, то конечно не обратишься из другого класса.
обе формы в public. по кнопке из одной формы должно меняться WindowTitle другой формы. все компилица, но когда нажимаю кнопку, вылетает с ошибкой сегментации
Подробнее механизм опять же в доках. Кажется в книжке Бланшета (или у Шлее) описано все это было...
странные книжки. вроде и много всего, а чего надо не найти))

попробую с сигналами и слотами разобраться...


Название: Re: управление окнами MDI
Отправлено: voronElf от Март 25, 2010, 11:40
Цитировать
вылетает с ошибкой сегментации
с инициализацией адресов окон посмотри или код выложи

Цитировать
странные книжки. вроде и много всего, а чего надо не найти))
ну это не справочники, они для изучения ...


Название: Re: управление окнами MDI
Отправлено: jerdeks от Март 25, 2010, 20:21
mainwindow.cpp:
Код:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "caesar.h"
#include <QMdiArea>
#include <QMdiSubWindow>

QWidget *widget;
caesar *form_caesar;

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

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

void MainWindow::changeEvent(QEvent *e)
{
    QMainWindow::changeEvent(e);
    switch (e->type()) {
    case QEvent::LanguageChange:
        ui->retranslateUi(this);
        break;
    default:
        break;
    }
}

void MainWindow::on_action_triggered()
{
    form_caesar = new caesar;
    ui->mdiArea->addSubWindow(form_caesar);
    form_caesar->show();
}

mainwindow.h:
Код:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

namespace Ui {
    class MainWindow;
}

[b]class caesar; // класс второй формы[/b]

class MainWindow : public QMainWindow {
    Q_OBJECT
public:
    MainWindow(QWidget *parent = 0);
    ~MainWindow();
    Ui::MainWindow *ui;
    [b]caesar* caesar_w;   // как сказали сделать указатель на вторую форму[/b]

protected:
    void changeEvent(QEvent *e);

private:

private slots:
    void on_action_triggered();

};

#endif // MAINWINDOW_H

caesar.cpp:
Код:
#include "caesar.h"
#include "ui_caesar.h"
#include "mainwindow.h"

caesar::caesar(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::caesar)
{
    ui->setupUi(this);
    QTextCodec::setCodecForLocale(QTextCodec::codecForName("Windows-1251"));
}

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

void caesar::changeEvent(QEvent *e)
{
    QWidget::changeEvent(e);
    switch (e->type()) {
    case QEvent::LanguageChange:
        ui->retranslateUi(this);
        break;
    default:
        break;
    }
}

void caesar::on_pushButton_clicked()
{
    mw->setWindowTitle("12345");
}

caesar.h:
Код:
#ifndef CAESAR_H
#define CAESAR_H

#include <QWidget>

namespace Ui {
    class caesar;
}

class MainWindow;

class caesar : public QWidget {
    Q_OBJECT
public:
    caesar(QWidget *parent = 0);
    ~caesar();
    MainWindow* mw;

protected:
    void changeEvent(QEvent *e);

private:
    Ui::caesar *ui;

private slots:
    void on_pushButton_clicked();

};

#endif // CAESAR_H


Эта прога, так-то алгоритм цезаря. Я про то, чтобы названию формы "caesar" не удилялись))


Название: Re: управление окнами MDI
Отправлено: voronElf от Март 26, 2010, 06:26
Код:
void caesar::on_pushButton_clicked()
{
    mw->setWindowTitle("12345");
}

не увдел, где значение mw инициалзизируется, если нигде, то из-за этого и вылетает

ну и мелочи: зачем в mainwindow.cpp глобальные переменные нужны ? глобальные переменные это зло


Название: Re: управление окнами MDI
Отправлено: jerdeks от Март 26, 2010, 09:29
не увдел, где значение mw инициалзизируется, если нигде, то из-за этого и вылетает

ааааа.. инициализироваться - это new, да? щас попробую


Название: Re: управление окнами MDI
Отправлено: jerdeks от Март 26, 2010, 09:56
в файле caesar.cpp написал

mw = new MainWindow;

вот такая вот ошибка:
error: expected constructor, destructor, or type conversion before ‘=’ token

перенес вот сюда:
Код:
caesar::caesar(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::caesar)
{
    ui->setupUi(this);
    lib.load();

    mw = new MainWindow; // <----
    QTextCodec::setCodecForLocale(QTextCodec::codecForName("Windows-1251"));
}

теперь компилица, даже кнопочка нажимается, но ничего не происходит


Название: Re: управление окнами MDI
Отправлено: voronElf от Март 26, 2010, 10:20
мда ...

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

Через параметр конструктора инициалзируй.

ПС: а если сейчас сделать mw->show(); удивительная вещь произойдет )))


Название: Re: управление окнами MDI
Отправлено: jerdeks от Март 26, 2010, 10:41
да уж.. )))

а как через параметр конструктора инициализировать?


Название: Re: управление окнами MDI
Отправлено: jerdeks от Март 26, 2010, 16:47
связал сигнал со слотом и все заработало. круто. но вопрос остается в силе


Название: Re: управление окнами MDI
Отправлено: voronElf от Март 29, 2010, 05:59
ну чтож, как-то так:

caesar.h:
Код:
class MainWindow;

class caesar : public QWidget {
    Q_OBJECT
public:
    caesar(MainWindow * mainWnd, QWidget *parent = 0);
    ~caesar();
private:
    MainWindow* mw;
.....


caesar.cpp :
Код:
caesar::caesar(MainWindow * mainWnd, QWidget *parent) :
    QWidget(parent),
    ui(new Ui::caesar)
{
    ui->setupUi(this);
    mw = mainWnd;
........
}

ну и использование в классе MainWindow:
Код:
void MainWindow::on_action_triggered()
{
    form_caesar = new caesar(this);
}