Название: Общение между двумя объектами! Отправлено: Racot от Апрель 14, 2012, 15:59 Код: int main(int argc, char *argv[]) У меня есть 2 формы классов MainWindow1 и MainWindow2.На каждой есть по кнопке, по нажатию которой должна появляется другая форма, а эта скрывается. То есть в слоте обработки нажатия на кнопку должно быть примерно так: Код: void MainWindow1::on_pushButton_clicked() но класс MainWindow1 ничего же не знает о объекте w2. Как это делается? Можно MainWindow1 *w и MainWindow2 *w2 объявлять глобально.Но я читал что это не правильно.(тем более допустим в java нет глобальных переменных, но там же как то это реализовывается). В общем кто реализовывал многооконные интерфейсы - помогите!! Название: Re: Общение между двумя объектами! Отправлено: alexis031182 от Апрель 14, 2012, 16:19 Вам нужно просто в обоих объектах класса MainWindow сохранять указатели друг на друга. Напишите в MainWindow функцию, например:
Код: void MainWindow::setCorrespondingWindow(MainWindow *mw) Код: MainWindow _mw; Название: Re: Общение между двумя объектами! Отправлено: kambala от Апрель 14, 2012, 16:29 как по мне, лучше это делать через отдельный класс-менеджер
Название: Re: Общение между двумя объектами! Отправлено: Racot от Апрель 14, 2012, 16:46 Как только создаю в каждом из классов указатели друг на друга.....то компилятор мне выдаёт -
Цитировать ..\Temp_pro\/mainwindow2.h:15: error: ISO C++ forbids declaration of 'MainWindow1' with no type ..\Temp_pro\/mainwindow2.h:15: error: expected ';' before '*' token alexis031182 вы сами пробывали? Цитировать как по мне, лучше это делать через отдельный класс-менеджер что есть класс-менеджер???Название: Re: Общение между двумя объектами! Отправлено: alexis031182 от Апрель 14, 2012, 16:56 как по мне, лучше это делать через отдельный класс-менеджер Да, конечно. А ещё можно вообще обойтись без сохранения указателей друг на друга и решить задачу через сигнал/слоты.Код: MainWindow1 *w = new MainWindow1(); Название: Re: Общение между двумя объектами! Отправлено: kambala от Апрель 14, 2012, 16:59 Как только создаю в каждом из классов указатели друг на друга.....то компилятор мне выдаёт - 1. допиши в заголовочных файлах соответственно class MainWindow1 и class MainWindow2Цитировать ..\Temp_pro\/mainwindow2.h:15: error: ISO C++ forbids declaration of 'MainWindow1' with no type ..\Temp_pro\/mainwindow2.h:15: error: expected ';' before '*' token alexis031182 вы сами пробывали? Цитировать как по мне, лучше это делать через отдельный класс-менеджер что есть класс-менеджер???2. отдельный класс (возможно наследник QObject), который будет показывать и скрывать нужное окно Название: Re: Общение между двумя объектами! Отправлено: alexis031182 от Апрель 14, 2012, 17:03 alexis031182 вы сами пробывали? :) не надо просто копипастить. Попробуйте разобраться.Указанная ошибка говорит о том, что Вы не добавили объявления классов друг на друга в их заголовки. Название: Re: Общение между двумя объектами! Отправлено: Racot от Апрель 14, 2012, 17:04 Цитировать 1. допиши в заголовочных файлах соответственно class MainWindow1 и class MainWindow2 в том то и беда что заголовочные файлы добавлены((((((( Название: Re: Общение между двумя объектами! Отправлено: Racot от Апрель 14, 2012, 17:07 mainwindow1.h
#ifndef MAINWINDOW1_H #define MAINWINDOW1_H #include <QMainWindow> #include "mainwindow2.h" namespace Ui { class MainWindow1; } class MainWindow1 : public QMainWindow { Q_OBJECT public: explicit MainWindow1(QWidget *parent = 0); ~MainWindow1(); /* void get_win2(MainWindow2 *win2) { mw2= win2; }*/ private slots: void on_pushButton_clicked(); private: Ui::MainWindow1 *ui; MainWindow2 *mw2; }; #endif // MAINWINDOW1_H ////////////////////////////////////////////////////////////////////////////////////////////////////////// mainwindow2.h #ifndef MAINWINDOW2_H #define MAINWINDOW2_H #include <QMainWindow> #include "mainwindow1.h" namespace Ui { class MainWindow2; } class MainWindow2 : public QMainWindow { Q_OBJECT public: explicit MainWindow2(QWidget *parent = 0); ~MainWindow2(); private: Ui::MainWindow2 *ui; MainWindow1 *mw1; }; #endif // MAINWINDOW2_H ничего не копипастил.......вот выдаёт ошибку Название: Re: Общение между двумя объектами! Отправлено: alexis031182 от Апрель 14, 2012, 17:11 А зачем Вам там namespace, да плюсом ещё и указатель на самого себя?
Название: Re: Общение между двумя объектами! Отправлено: Racot от Апрель 14, 2012, 17:15 Цитировать А зачем Вам там namespace, да плюсом ещё и указатель на самого себя? Вы про это? namespace Ui { class MainWindow1; } private: Ui::MainWindow1 *ui; так это QtCreator сам код создаёт.дело точно не в этом. Название: Re: Общение между двумя объектами! Отправлено: alexis031182 от Апрель 14, 2012, 17:21 Вы про это? Да.... так это QtCreator сам код создаёт.дело точно не в этом. А ну понял. Я не пользуюсь этим функционалом, поэтому обратил внимание, что вроде показалось мне излишним. Ну да ладно. Так-то вроде всё верно написано. Попробуйте очистить проект и заново пересобрать.Название: Re: Общение между двумя объектами! Отправлено: Racot от Апрель 14, 2012, 17:27 очистил.пересобрал. та же ошибка.
Название: Re: Общение между двумя объектами! Отправлено: alexis031182 от Апрель 14, 2012, 17:29 В обоих файлах:
Код: namespace Ui { Название: Re: Общение между двумя объектами! Отправлено: kambala от Апрель 14, 2012, 17:32 Код
Название: Re: Общение между двумя объектами! Отправлено: Racot от Апрель 14, 2012, 17:39 Цитировать class MainWindow2; // тут должен быть "противоположный" класс а я думал что если хедер вставил то и объявлять не надо класс..... Всем спасибо! помогло!!!!!!! Название: Re: Общение между двумя объектами! Отправлено: kambala от Апрель 14, 2012, 18:24 вот как раз хедер лучше подключать не в .h, а в .cpp
Название: Re: Общение между двумя объектами! Отправлено: Racot от Апрель 14, 2012, 18:50 и то верно ;D
Название: Re: Общение между двумя объектами! Отправлено: Igors от Апрель 15, 2012, 10:00 Решение сохранять указатели будет работать, но оно немногим лучше глобальных переменных. В обоих случаях 2 класса "знают" друг о друге, образуется "зависимость". Пока задача достаточно проста все нормально. Но предположим появился MainWindow3, т.е. переключаться надо уже между 3 формами. Переделать указатели будет совсем не легко.
Более капитальное (и правильное) решение указал kambala. Просто можно не спешить с классом-менеджером, а пока сделать так - кнопки в окнах испускают сигналы - в main (пока) эти сигналы связываются со слотами hide/show окон Когда возникнет необходимость в более сложном переключении - мы свяжем сигналы уже с чем-то другим (там видно будет), но нам не придется кромсать MainWindow1(2, 3) Название: Re: Общение между двумя объектами! Отправлено: alexis031182 от Апрель 15, 2012, 10:44 ... Кнопки на формах, а значит любую из них нельзя подключить к "противостоящей" форме. Соответственно, только через самопальные сигналы форм. Впрочем, труда здесь безусловно немного.Более капитальное (и правильное) решение указал kambala. Просто можно не спешить с классом-менеджером, а пока сделать так - кнопки в окнах испускают сигналы - в main (пока) эти сигналы связываются со слотами hide/show окон ... Название: Re: Общение между двумя объектами! Отправлено: Racot от Апрель 17, 2012, 20:45 Гм.........я уже думал что "познал смысл жизни".......но Igors (похоже что умный мужик) опять меня запутал. А как делается там где нет сигналов и слотов(не в QT)??? Я просто не силён в ООП и хотел добраться до истины - "как делается это у нормальных людей?". Наверняка это тривиальная задача сделать интерфейс из нескольких главных окон(которая проделывалась тысячи раз тысячами людьми).
И я почти был уверен что это делается средствами ООП и C++(это же просто общение двух объектов). Название: Re: Общение между двумя объектами! Отправлено: Tonal от Апрель 18, 2012, 09:50 Сигналы/слоты тоже не содержат ничего магического. Там указатели на объекты и их функции. Просто в рамках Qt это автоматизировано с помощью дополнительных ключевых слов и генерации кода - специализированного препроцессора.
В чистом С/С++ весь этот код нужно писать руками. Правда есть некоторое количество библиотек сокращающих писанину. :) В Qt можно придерживаться простого правила: Дочерний виджет не знает интерфейса родителя, а родительский знает интерфейс дочернего. Это приводит к тому, что дочерний посылает сигналы, когда ему есть, что сказать, а родительский вызывает функции дочерних, когда ему это зачем-то нужно. :) Т. е. родительский выступает для своих дочерних менеджером, о котором писал kambala. Иногда, можно в родительском просто связать сигнал/слоты дочерних, иногда требуется какая-то более сложная обработка. |