Название: Закрытие/открытие формы. Отправлено: newbie от Сентябрь 27, 2016, 05:27 Здравствуйте!
В qt тотальный новичок, поэтому возникают дурацкие вопросы, например: как правильно закрыть форму? Судя по гуглу, вопрос распространённый, но решения, которое сработало бы для меня, я не нашёл. Справку читал, но не всегда могу там найти ответы (как сейчас, например). Суть: при закрытии формы закрывается вся программа, вместо того, чтобы закрыть окно. Как это исправить? Подробнее: у меня есть форма класса "start_Form", она "QWidget". На ней есть кнопка, открывающая главное окно класса "Main_Window", оно "QMainWindow". В главном окне через меню вызывается ещё одна форма класса "edit_Form", которая "QWidget". Нужно, чтобы по нажатию кнопки на start_Form, открывалась главное окно, а начальная форма пряталась, и наоборот — при закрытии главного окна появлялась start_Form. Это дело я реализовал так: Код: // start_form.cpp Код: // main_window.cpp P.S. Несколько вопросов, если не сложно ответьте и на них или дайте ссылки, где можно найти ответ. 1) В форме edit_Form, если я использую Код: void closeEvent(QCloseEvent *event) Q_DECL_OVERRIDE; 2) Обязательно ли писать "event->accept();"? Зачем он нужен в справке написано, но всё же зачем он, если и без него работает (проверил)? 3) Где лучше писать connect и объявлять переменные классов форм? Сначала делал это в конструкторе start_Form, но потом перенёс их на кнопки. Работает и там, и там. Название: Re: Закрытие/открытие формы. Отправлено: __Heaven__ от Сентябрь 27, 2016, 11:10 Во вложении пример с переключением видимости форм. Оговорюсь, что не самый лучший, так как не до конца понял, что из себя представляет программа.
Название: Re: Закрытие/открытие формы. Отправлено: Bepec от Сентябрь 27, 2016, 11:16 Поможет вам вот такая вот строка :D
Код: qApp->setQuitOnLastWindowClosed(false); PS qApp - это указатель на QApplication, следовательно хедер #include <QApplication> должен быть включен обязательно :) Название: Re: Закрытие/открытие формы. Отправлено: __Heaven__ от Сентябрь 27, 2016, 11:47 Цитировать при закрытии формы закрывается вся программа, вместо того, чтобы закрыть окно. Как это исправить? Самое простое - не закрывать все формы, так как по умолчанию это интерпретируется как выход из программы.Цитировать компилятор говорит: "invalid use of incomplete type 'class QCloseEvent'" Дело в том, что на момент использования экземпляра QCloseEvent сам класс является объявленным, но не определённым. Это позволяет таскать указатель на этот экземпляр, но не позволяет разыменовывать его для обращения к методам QCloseEvent. Решение: Код
Цитировать 3) Где лучше писать connect и объявлять переменные классов форм? Сначала делал это в конструкторе start_Form, но потом перенёс их на кнопки. Работает и там, и там. Если на кнопки переносить, то будет по каждому щелчку вызываться лишний (кроме первого) connect. Рекомендую завести отдельный метод для коннектов и вызывать его в конструкторе класса формы. Где объявлять переменные класса формы - зависит от задачи. Если имеется "родительство" одной формы над другой, то, имхо, лучше дочернюю форму сделать членом класса родительской формы.Название: Re: Закрытие/открытие формы. Отправлено: __Heaven__ от Сентябрь 27, 2016, 12:00 Цитировать 2) Обязательно ли писать "event->accept();"? Зачем он нужен в справке написано, но всё же зачем он, если и без него работает (проверил)? Не пользовался этим, но судя по описаниям справки у нас в QEvent по умолчанию флаг accepted принят true, но не стоит на это полагаться, так как классы наследники могут назначить ему false в своих конструкторах. У QCloseEvent по умолчанию этот флаг в положении true. Если мы хотим отменить процесс закрытия окна, то переводим его в false, иначе просто ничего не делаем. Но также существует вероятность, что экземпляр QCloseEvent может прилететь в метод с выставленным флагом false, например из какого-то наследника, который решил отменить закрытие формы, а вы своим кодомКод насильно заставляете его закрыться. Название: Re: Закрытие/открытие формы. Отправлено: Igors от Сентябрь 27, 2016, 12:18 Большинство приложений используют примерно такой подход
Есть MainWindоw - главное окно, всегда только одно и "на всю жизнь". Закрытие MainWindоw означает закрытие приложения. Часто оно вообще всегда видимо. Если по каким-то причинам это не устраивает - скройте его методом hide, но не удаляйте. Все остальные окна - чайлды MainWindоw. Тогда легко узнать какие окна сейчас созданы/видимы даже не храня никаких указателей, напр Код Также есть смысл сделать var_main_window синглтоном (глобальной переменной) чтобы не чикаться со слот/сигналами а звать его методы напрямую Название: Re: Закрытие/открытие формы. Отправлено: __Heaven__ от Сентябрь 27, 2016, 12:48 Не рекомендую
Код: qApp->setQuitOnLastWindowClosed(false); Потому, что на мой взгляд он не решит проблему, так как в любом случае переключение окон будет осуществляться тогда, когда хотя бы одно из них не закрыто, то есть в момент закрытия. Но при этом ещё придётся заботиться о выходе из приложения. Также, считаю, что findChild не совсем удобный инструмент. ИМХО, гораздо проще хранить дочерние формы в виде членов класса. Это позволит избежать лишних проверок и конструирования элемента ручками. Мне кажется, что не стоит делать глобальным главное окно ради удобств вызова слотов. Такое решение жёстко связывает классы и может стать проблемой для дальнейшего повторного использования дочернего класса. Название: Re: Закрытие/открытие формы. Отправлено: Bepec от Сентябрь 27, 2016, 14:11 Любое ваше решение кроме setQuitLastWindow несёт ограничения :D
Как то члены класса, как то сиглтон/главное окно. Они не хуже, но используются в разных ситуациях :D Название: Re: Закрытие/открытие формы. Отправлено: __Heaven__ от Сентябрь 27, 2016, 14:24 Bepec, а можете сделать примерчик с использованием setQuitLastWindow? Я не совсем понимаю, где вы его использовать собираетесь.
Название: Re: Закрытие/открытие формы. Отправлено: Bepec от Сентябрь 27, 2016, 14:52 Вы прочитайте название темы, вопрос тсса и поймете где его будет использовать ТС, Igors, Вы и любой пожелавший :D
PS то, что вы с Igors развили тему, это хорошо. Плохо, что вы не ответили на главный вопрос ТСса, а стали придумывать "костыли". PPS если даже так непонятно, то добавление этой строчки заставит работать программу ТСса предсказуемо для него. Точка. Проблема решена, основной вопрос закрыт. Название: Re: Закрытие/открытие формы. Отправлено: newbie от Сентябрь 27, 2016, 15:01 Во-первых, всем большое спасибо за ответы.
А во-вторых, третьих и т.д.: С ответами на доп. вопросы вроде разобрался, по основному же Цитировать qApp->setQuitOnLastWindowClosed(false); действительно работает, но не так, как хотелось бы. Окно формы закрывается, но не уничтожается, т.е. новом открытии формы edit_Form создаётся вторая форма edit_Form и красуется рядом с первой. Плюс, при закрытии всех окон, процесс остаётся висеть в системе. Сделал всем окнам Код: var_start_form.setAttribute(Qt::WA_DeleteOnClose); Что я делаю не так, и как это исправить? Цитировать Цитировать при закрытии формы закрывается вся программа, вместо того, чтобы закрыть окно. Как это исправить? Самое простое - не закрывать все формы, так как по умолчанию это интерпретируется как выход из программы.P.S. В процессе снова возникла пара доп. вопросов: 1) Код: qApp->setQuitOnLastWindowClosed(false); 2) На момент написания думал, что в форме создавать главное окно так себе индусня, но не хотел переписывать. Сейчас решил это переделать, и столкнулся со следующей проблемой (которая, правда, была и до этого): Код: // var_start_window создаётся в главном окне QMainWindow. 3) Можно ли часть ответа под спойлером прятать? А то у меня полотна какие-то получаются :) Название: Re: Закрытие/открытие формы. Отправлено: Igors от Сентябрь 27, 2016, 15:21 var_start_window = new start_Form(this); // 2-ой. Не работает. Укажите что создаете окно, а не просто виджет Когда я главным окном (QMainWindow) создаю форму (QWidget), то в первом варианте всё замечательно, окно появляется. Во втором случае же новое окно не появляется, его интерфейс отображается поверх интерфейса главного окна. Код
Плохо, что вы не ответили на главный вопрос ТСса, а стали придумывать "костыли". У Вас забыли спроситьPPS если даже так непонятно, то добавление этой строчки заставит работать программу ТСса предсказуемо для него. Точка. Проблема решена, основной вопрос закрыт. Здесь нужно не строчки менять а метод/подходНазвание: Re: Закрытие/открытие формы. Отправлено: __Heaven__ от Сентябрь 27, 2016, 15:42 newbie, советую ещё посмотреть класс QDialog.
|