Russian Qt Forum
Ноябрь 26, 2024, 13:28 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Работа нескольких форм.  (Прочитано 11317 раз)
Mish_ka
Гость
« : Март 23, 2011, 17:52 »

Подскажите пожалуйста, догнать сам не могу.

Есть форма1 и форма2

из main.cpp, вызываю функцию на форме1 (по открытию формы2), при этом форма1 скрытая.

код майна:
Код
C++ (Qt)
Form1 frmOne;
frmOne.showfrmTwo();
frmOne.setVisible(false);
 

код функции вызова формы2 - суть функции запустить форму 2, запустить таймер, по истечении которого на форме 2 должна стать кнопка btn активной, по кнопке btn должна закрыться вторая форма т отобразиться первая.
Код
C++ (Qt)
frmTwo = new Form2(0);
frmTwo->setVisible(true);
timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(showbtnfrm2()));
timer->setSingleShot(true);
timer->start(3000);
 

функция showbtnfrm2() - вызывает глобальную функцию с формы2
Код
C++ (Qt)
frmTwo ->btnGoON();
 

функция btnGoON() - на форме2 делает кнопку активной
Код
C++ (Qt)
ui.btn->setEnabled(true);
 

на кнопку висит конект
Код
C++ (Qt)
connect(ui.btn, SIGNAL(clicked()), this, SLOT(hideMe()));
 

функция hideMe() - на форме2 вызывает глобальную функцию hideTwo() на форме1
Код
C++ (Qt)
frm1->hideTwo();
 

функция hideTwo() - на форме1 должна убивать вторую форму и показывать первую
Код
C++ (Qt)
this->setVisible(true);
delete frmTwo;
 

В такой комбинации вылетает крах проги.
Если закоментить первую строку то вторая форма убивается нормально, а первая соответственно не показывается=).

голову уже сломал Непонимающий
Записан
Denjs
Гость
« Ответ #1 : Март 23, 2011, 19:09 »

во первых никак нельзя "delete frmTwo;"
можно "frmTwo->deleterlater();"
Иначе рискуете сегфолт схватить из глубоких недр Qt.

Во вторых - чего то у вас слишком много фрагментов. Полностью код опубликуйте?
Мне вот уже не нравится что вы "из main.cpp, вызываю функцию на форме1" потому что делать что то с формой вне eventLoop - меня это лично как-то сильно коробит. Тем более - боюсь что вы и от таймера чего-то ждете вне цикла событий... имхо, не люблю я такое, да и не понятно что у вас там и как именно. Давайте весь код.

и проблему опишите "локальнее" - в одном абзаце лаконично, а то я, признаться, так ничего и не понял что вам в этом всем не нравится.
Записан
Mish_ka
Гость
« Ответ #2 : Март 23, 2011, 19:28 »

Проблема:
Хочу чтобы из первой формы вызывалась вторая
при этом первая форма скрыта, и считает время для активации кнопки закрытия второй формы
Закрытие второй формы и отображение первой.

У меня в приведённом ниже коде не получается только отобразить первую форму (проблемная строчка помечена).

Полный код:
майн
Код
C++ (Qt)
#include "itman.h"
#include <QtGui>
#include <QApplication>
 
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
app.setQuitOnLastWindowClosed(false);
 
iTMan frmMainWindows;
frmMainWindows.showStartBaner();
 
return app.exec();
}
 

первая форма
Код
C++ (Qt)
#include "itman.h"
#include "startbaner.h"
 
#include <QTimer>
 
QTimer *timer;
startBaner *frmSB;
 
iTMan::iTMan(QWidget *parent): QMainWindow(parent)
{
uiIT.setupUi(this);
}
 
// показываем стартовый банер
void iTMan::showStartBaner()
{
frmSB = new startBaner(0);
frmSB->setVisible(true);
timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(showSBbtnGo()));
timer->setSingleShot(true);
timer->start(intTimeOfSB);
}
 
//прячем стартовый банер
void iTMan::hideStartBaner()
{
this->setVisible(true); /////////////////////////// Вот здесь что написать??????????????????????????????????????????????????
delete frmSB;
}
 
void iTMan::showSBbtnGo()
{
frmSB->btnGoON();
}
 

вторая форма
Код
C++ (Qt)
#include "startbaner.h"
#include "itman.h"
 
iTMan *frmIT;
 
startBaner::startBaner(QWidget *parent): QWidget(parent)
{
uiSB.setupUi(this);
 
connect(uiSB.btnGo, SIGNAL(clicked()), this, SLOT(hideMe()));
 
uiSB.btnGo->setEnabled(false);
}
 
void startBaner::btnGoON()
{
uiSB.btnGo->setEnabled(true);
}
 
void startBaner::hideMe()
{
frmIT->hideStartBaner();
}
 

Записан
Denjs
Гость
« Ответ #3 : Март 24, 2011, 00:57 »

во первых, я бы

QTimer *timer; и startBaner *frmSB;  
 - определил как свойства класса iTMan. Зачем они просто так висят?... весь ООП портят)

Во вторых - у вас нифига не инициируется  iTMan *frmIT (который тоже надо бы в свойства класса перенести);

про запутанность соединений я промолчу...

В третьих я так понимаю вы показали форму, тсчитали время, и ждете пока пользователь нажмет кнопку?
Ну.. он её нажимает.. и? void startBaner::hideMe() вызывается? void iTMan::hideStartBaner() вызывается?
а в момент "connect(uiSB.btnGo, SIGNAL(clicked()), this, SLOT(hideMe()));" - вы никаких warning в консоль не получаете по поводу невозможности подключиться? а  iTMan *frmIT точно инициировали?
Записан
Mish_ka
Гость
« Ответ #4 : Март 24, 2011, 09:15 »

Нет ни каких Варингов не сыпиться.
*frmIT инициируется так как вызов происходит:
Код
C++ (Qt)
void startBaner::hideMe()
{
frmIT->hideStartBaner();
}

трабла уже в функции hideStartBaner();
Код
C++ (Qt)
void iTMan::hideStartBaner()
{
this->setVisible(true); /////////////////////////// Вот здесь что написать??????????????????????????????????????????????????
delete frmSB;
}

если нет строчки this->setVisible(true); то вторая форма убивается, а приложение продолжает висеть в процессах.

Вопрос как в данной ситуации показать не видимую первую форму
Записан
Denjs
Гость
« Ответ #5 : Март 24, 2011, 11:35 »

тогда прикрепляйте ваши файлы вашего проекта в архиве и просите что бы кто-то для вас - собрал у себя вашу программу и прогнал под отлдачиком у себя.
имхо.
Записан
Mish_ka
Гость
« Ответ #6 : Март 24, 2011, 12:50 »

Вот исходники

+ видео =)
http://narod.ru/disk/8295651001/24.03.2011%2018-37-59.rar.html
Записан
m4n71k0r
Гость
« Ответ #7 : Март 24, 2011, 16:11 »

Извиняюсь, а дро...{передёргивать} память таким вот образом модно стало?
Создали формы и делайте видимыми/невидимыми.

Upd: http://doc.qt.nokia.com/4.7/qsplashscreen.html
« Последнее редактирование: Март 24, 2011, 16:17 от m4n71k0r » Записан
Mish_ka
Гость
« Ответ #8 : Март 24, 2011, 16:48 »

Если не заметили то при заданных условиях ваш сплэш (qsplashscreen) не катит...

Просто я думал что это не есть дрочево =)

я с VB

там проще, есть прога, в ней есть формы.

Me.frmForm.show - показывает
Me.frmForm.hide - скрывает

вызываются из любого места.


Подскажите тогда как делать такие манипуляции и не дрочить память =)
Записан
m4n71k0r
Гость
« Ответ #9 : Март 24, 2011, 21:42 »

two_forms_and_timer.pro

Код
C++ (Qt)
QT += gui core
SOURCES += \
   core.cpp
 
HEADERS += \
   banner_form.hpp \
   main_form.hpp
 

banner_form.hpp

Код
C++ (Qt)
#ifndef BANNER_FORM_HPP
#define BANNER_FORM_HPP
 
#include <QWidget>
#include <QPushButton>
 
class banner_form: public QWidget
{
 Q_OBJECT
 
public:
 
 QPushButton *go_button;
 
 explicit banner_form(QWidget *parent = 0):
     QWidget(parent)
 {
   go_button = new QPushButton("<<GO>>", this);
   go_button->setEnabled(false);
   connect(go_button, SIGNAL(clicked()), this, SLOT(close()));
   move(100, 100);
   resize(300,300);
 }
 
public slots:
 
 void enable_go_button()
 {
   go_button->setEnabled(true);
 }
};
#endif // BANNER_FORM_HPP
 

main_form.hpp

Код
C++ (Qt)
#ifndef MAIN_FORM_HPP
#define MAIN_FORM_HPP
 
#include <QWidget>
#include <QTimer>
#include "banner_form.hpp"
 
class main_form: public QWidget
{
 Q_OBJECT
 
 QTimer      *main_timer;
 banner_form *banner;
 
public:
 
 explicit main_form(QWidget *parent = 0, banner_form *banner_ = 0):
     QWidget(parent), banner(banner_)
 {
   main_timer = new QTimer(this);
 
   main_timer->setSingleShot(true);
   connect(main_timer, SIGNAL(timeout()), banner, SLOT(enable_go_button()));
   connect(banner->go_button, SIGNAL(clicked()), this, SLOT(show()));
 
   move(0, 0);
   resize(500, 500);
   setVisible(false);
 }
 
 void start_timer()
 {
   main_timer->start(3000);
 }
};
#endif // MAIN_FORM_HPP
 

core.cpp

Код
C++ (Qt)
#include <QApplication>
#include <QtGui>
 
#include "banner_form.hpp"
#include "main_form.hpp"
 
int main(int args_number, char *args[])
{
 QApplication main_app(args_number, args);
 
 banner_form *simple_banner_form     = new banner_form();
 main_form   *just_another_main_form = new main_form(0, simple_banner_form);
 
 just_another_main_form->activateWindow();
 
 simple_banner_form->show();
 just_another_main_form->start_timer();
 
 return main_app.exec();
}
 

Извиняюсь, местами нарушил принципы ООП (в частности, не полностью выполнил инкапсуляцию).
Удачи.

И определитесь, на каком языке программирования Вы будете писать профессионально.

Upd: Можно просто создать Ваш класс диалогового окна. Ещё неплохо бы сделать обработчик события нажатия кнопки и по нажатию генерировать сигнал от формы, что кнопка нажата. Таким образом все объекты баннера будут скрыты и на выходе будет лишь сигнал о нажатии кнопки, который будет оповещать главную форму, что нужно появиться...А я бы просто сделал модальное окно и не заморачивался бы с невидимостью главной формы. У модального окна убрать все кнопки из заголовка и закрывать только по нажатию кнопки. Как вариант.
« Последнее редактирование: Март 25, 2011, 08:52 от m4n71k0r » Записан
Denjs
Гость
« Ответ #10 : Март 24, 2011, 23:33 »

Вот исходники
<...>
Ещё раз напомню вам про то что вы нигде не инициируете переменную frm1.

Цитировать
*frmIT инициируется так как вызов происходит:
Послушайте, вы хотите мне сказать, что если просиходит вызов, но вы нигде не иниуиировали переменную - то она сама чем-то инициировалась? позвольте тогда спросить - на что именно она указывает?!

Запустите программу под отладчиком, посомтрите значение переменной frm1 внутри From2::zakritEtuFormu() а потом на значение указателя this внутри Form2forM::PokazatFormu1_skritFormu2(). - это все в коде который вы приложили. Если произошел вызов метода по ссылке для неинициированной переменной - то значит вам просто "повезло" - и это частный соучай повеления частного компилятора в частном случае. В общем случае вы должны были схватить сегфолт при самой такой попытке вызова.
 Что бы объснить вам почему такое возможно - надо будет подробно и далеко залазить в дебри того, как С\С++ компиляторы хранять в памяти данные и методы классов.
А вы сомневаюсь, что готовы к такому.

Пока вы не инициировали переменную - у неё случайное значение. нельзя ею пользоваться.
Просто запомните это и переписывайте ваш код.
« Последнее редактирование: Март 24, 2011, 23:37 от Denjs » Записан
Mish_ka
Гость
« Ответ #11 : Март 30, 2011, 18:23 »

two_forms_and_timer.pro

Спасибо большое!
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.349 секунд. Запросов: 21.