Russian Qt Forum

Qt => Пользовательский интерфейс (GUI) => Тема начата: Evgeniya от Июль 13, 2009, 09:06



Название: как организовать закрытие формы,если в ней были открыты другие формы
Отправлено: Evgeniya от Июль 13, 2009, 09:06
Приветствую всех!!!
У меня есть несколько классов с формами..из одного класса вызывается второй, а из второго-третий...и вот мне надо, чтобы при закрытии самой первой формы закрывались все остальные,которые открыты..как это правильно организовать, подскажите пожалуйста!!!Я так полагаю,что нужно перегрузить функцию closeEvent(QCloseEvent *event)


Название: Re: как организовать закрытие формы,если в ней были открыты другие формы
Отправлено: lit-uriy от Июль 13, 2009, 09:17
можно удалять исходную по закрытию (ключевое слово: DeleteOnClose)


Название: Re: как организовать закрытие формы,если в ней были открыты другие формы
Отправлено: Evgeniya от Июль 13, 2009, 10:48
Вставляю при вызове в конструкторе самого первого класса:
this->setAttribute(Qt::WA_DeleteOnClose);
теперь при закрытии самой первой формы закрываются и остальные, но в процессах они остаются все почему-то  :(


Название: Re: как организовать закрытие формы,если в ней были открыты другие формы
Отправлено: Evgeniya от Июль 13, 2009, 13:25
И вот при этом, при открытии из первого окна второго, а потом при закрытии первого ... вызывается сначало деструктор первого класса, затем деструктор вторго, а потом почему-то опять вызывается деструктор первого...


Название: Re: как организовать закрытие формы,если в ней были открыты другие формы
Отправлено: Evgeniya от Июль 13, 2009, 14:43
Разобралася...создала самую первую форму(которая в main вызывается) в куче и сейчас вроде все нормально работает...значит в этом была причина.
или я ошибаюся???


Название: Re: как организовать закрытие формы,если в ней были открыты другие формы
Отправлено: Evgeniya от Июль 13, 2009, 15:05
все конечно нормано работает, только из памяти это приложение не удаляется :((


Название: Re: как организовать закрытие формы,если в ней были открыты другие формы
Отправлено: pastor от Июль 13, 2009, 15:09
Выложи сюда исходный код


Название: Re: как организовать закрытие формы,если в не
Отправлено: Evgeniya от Июль 13, 2009, 15:35
main.cpp
Код
C++ (Qt)
#include "auct.h"
 
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
   QTextCodec *codec=QTextCodec::codecForName("CP1251");
    QTextCodec::setCodecForCStrings(codec);
    Auct *w= new Auct(0);
    w->show();
    return a.exec();
}
 
auct.cpp
Код
C++ (Qt)
#include "auct.h"
 
Auct::Auct(QWidget *parent)
    : QMainWindow(parent)
{
connection();
ui.setupUi(this);
auct=new QSqlQueryModel(0);
str="SELECT auction.id,Method_razm.Name,auction.Num_izv,Format(auction.Date_auct,'dd.mm.yyyy') "
        "FROM auction INNER JOIN Method_razm ON auction.rf_methodID=Method_razm.id";
auct->setQuery(str,db);
ui.tableView->setModel(auct);
ui.tableView->hideColumn(0); connect(ui.tableView,SIGNAL(doubleClicked(QModelIndex)),this,SLOT(lpu()));
this->setAttribute(Qt::WA_DeleteOnClose);
}
Auct::~Auct()
{
  if(db.isOpen()) db.close();
}
void Auct::connection(){
db = QSqlDatabase::addDatabase("QODBC");
db.setDatabaseName("ls");
if(!db.open()){
QMessageBox::critical(0,"Ошибка подключения",db.lastError().text());
}
}
void Auct::lpu(){
int auctid;
  sel=ui.tableView->selectionModel();
  index=sel->currentIndex();   
auctid=auct->data(auct->index(index.row(),0)).toInt();
zak= new Zakazchik(this,auctid);
zak->show();
}
 
auct.h
Код
C++ (Qt)
#ifndef AUCT_H
#define AUCT_H
 
#include <QtGui/QMainWindow>
.....
 
 
#include "ui_Auct.h"
#include "zakazchik.h"
 
class Zakazchik;
class Auct : public QMainWindow
{
&#160; &#160; Q_OBJECT
 
public:
&#160; &#160; Auct(QWidget *parent = 0);
&#160; &#160; ~Auct();
&#160; &#160; void connection();
 
&#160; &#160; QSqlDatabase db;
&#160; &#160; QSqlQueryModel *auct;
&#160; &#160; QString str;
&#160; &#160; QModelIndex index;
&#160; &#160; QItemSelectionModel *sel;
&#160; &#160; Zakazchik *zak;
private:
&#160; &#160; Ui::AuctClass ui;
private slots:
&#160; &#160; void lpu();
};
#endif // AUCT_H
 

zakazchik.cpp
Код
C++ (Qt)
Zakazchik::Zakazchik(QWidget *parent,int auctID)
&#160; &#160; : QMainWindow(parent)
{
ui.setupUi(this);
auct.setNum(auctID);
db=QSqlDatabase::database();
zakazch=new QSqlQueryModel(0);
str="SELECT zakazchik.id,LPU.Name_LPU,LPU.INN,LPU.KPP,LPU.OGRN from "
&#160;&#160; "zakazchik INNER JOIN LPU ON zakazchik.rf_LPUID=LPU.Cod "
&#160;&#160; "where zakazchik.rf_auctID="+auct+"";
zakazch->setQuery(str);
ui.tableLPU->setModel(zakazch);
connect(ui.add_lpu,SIGNAL(clicked()),this,SLOT(add_lpu()));
connect(ui.tableLPU,SIGNAL(doubleClicked(QModelIndex)),this,SLOT(zakaz()));
connect(ui.otm,SIGNAL(clicked()),this,SLOT(close()));
title=st;
}
Zakazchik::~Zakazchik()
{
 
}
 
  а в этом классе(в слоте zakaz()) вызывается еще 3 класс


Название: Re: как организовать закрытие формы,если в ней были открыты другие формы
Отправлено: Evgeniya от Июль 13, 2009, 17:34
Видимо потому что я в деструктории память не освобождаю....
А как проверить вообще был ли создан объект...просто у меня вторая форма создается только по слоту, поэтому не всегда м.б. создана. Значит и удалять ее нужно только когда она создана...подскажите функцию, если такая есть


Название: Re: как организовать закрытие формы,если в ней были открыты другие формы
Отправлено: lit-uriy от Июль 13, 2009, 17:43
>> а в этом классе(в слоте zakaz()) вызывается еще 3 класс
покажи основу этого слота, как объект создаётся.


Название: Re: как организовать закрытие формы,если в ней были открыты другие формы
Отправлено: Evgeniya от Июль 13, 2009, 17:47
Код
C++ (Qt)
void Zakazchik::zakaz(){
int zakazchid;
sel=ui.tableLPU->selectionModel();
index=sel->currentIndex();
zakazchid=zakazch->data(zakazch->index(index.row(),0)).toInt();
z=new Zakaz(this,zakazchid);
z->show();
}

Я кажется решила эту проблему...просто в деструкторе вызываемого класса Zakazchik добавила delete this; ... только насколько это правильно ???


Название: Re: как организовать закрытие формы,если в ней были открыты другие формы
Отправлено: Evgeniya от Июль 13, 2009, 17:52
и теперь при закрытии главного окна закрываются дочерние и он не висит в памяти...

А вот если я создаю QTableView, например вот так
QTableView *tab=new QTableView(0);
tab->show();
Мне потом надо в деструкторе освобождать память и писать delete tab;
или в этом случае при удалении класса, из которого вызывается tab, об этом беспокоится деструктор QTableView??


Название: Re: как организовать закрытие формы,если в ней были открыты другие формы
Отправлено: lit-uriy от Июль 13, 2009, 19:13
>>Мне потом надо в деструкторе освобождать память и писать delete tab;
Надо так как ты не задаёшь родителя ( QTableView(0) )
А заботится об удалении детей именно родитель


Название: Re: как организовать закрытие формы,если в ней были открыты другие формы
Отправлено: Evgeniya от Июль 14, 2009, 08:07
>>Мне потом надо в деструкторе освобождать память и писать delete tab;
Надо так как ты не задаёшь родителя ( QTableView(0) )
А заботится об удалении детей именно родитель
а tab->close() не прокатит??


Название: Re: как организовать закрытие формы,если в ней были открыты другие формы
Отправлено: ufna от Июль 14, 2009, 10:35
Если есть у нее WA_DeleteOnClose, то прокатит.


Название: Re: как организовать закрытие формы,если в ней были открыты другие формы
Отправлено: Evgeniya от Июль 15, 2009, 08:25
Так и не получается решить данную проблему...:((
Выкладыаю простенький код
main.cpp
Код
C++ (Qt)
#include "main_form.h"
 
#include <QtGui>
#include <QApplication>
 
int main(int argc, char *argv[])
{
   QApplication a(argc, argv);
   QTextCodec *codec=QTextCodec::codecForName("CP1251");
   QTextCodec::setCodecForCStrings(codec);
   main_form *w=new main_form(0);
   w->show();
   return a.exec();
}
 
main_form.cpp
Код
C++ (Qt)
#include "main_form.h"
 
main_form::main_form(QWidget *parent)
   : QMainWindow(parent)
{
ui.setupUi(this);
this->setWindowTitle("Главная");
setAttribute(Qt::WA_DeleteOnClose);
connect(ui.pushButton,SIGNAL(clicked()),this,SLOT(sl()));
}
 
main_form::~main_form()
{
//QMessageBox::information(0,"деструктор","для main_form");
}
void main_form::sl(){
 t=new doch(this);
 t->show();
}
 
main_form.h
Код
C++ (Qt)
#ifndef MAIN_FORM_H
#define MAIN_FORM_H
 
#include <QtGui/QMainWindow>
#include "ui_main_form.h"
#include "doch.h"
 
class doch;
class main_form : public QMainWindow
{
   Q_OBJECT
 
public:
   main_form(QWidget *parent = 0);
   ~main_form();
   doch *t;
 
private:
   Ui::main_formClass ui;
private slots:
   void sl();
};
 
#endif // MAIN_FORM_H
 
doch.cpp
Код
C++ (Qt)
#include "doch.h"
 
doch::doch(QWidget *parent)
   : QMainWindow(parent)
{
ui.setupUi(this);
this->setWindowTitle("дочерняя");
}
 
doch::~doch()
{
//QMessageBox::about(0,"деструктор","для two");
}
 
doch.h
Код
C++ (Qt)
#ifndef DOCH_H
#define DOCH_H
 
#include <QtGui/QMainWindow>
#include <QMessageBox>
#include <QCloseEvent>
#include "ui_doch.h"
 
class doch : public QMainWindow
{
   Q_OBJECT
 
public:
   doch(QWidget *parent = 0);
   ~doch();
 
private:
   Ui::DochClass ui;
};
 
#endif

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


Название: Re: как организовать закрытие формы,если в ней были открыты другие формы
Отправлено: spectre71 от Июль 15, 2009, 10:49
Так лучше
Код
C++ (Qt)
int main(int argc, char *argv[])
{
   QApplication a(argc, argv);
   QTextCodec *codec=QTextCodec::codecForName("CP1251");
   QTextCodec::setCodecForCStrings(codec);
   main_form w;
   w.show();
   return a.exec();
}


Название: Re: как организовать закрытие формы,если в ней были открыты другие формы
Отправлено: Evgeniya от Июль 15, 2009, 11:00
Да,но тогда в таком случае выскакивает системная ошибка :(((, т.к. в таком случае вызываются 2 деструктора...у меня же установлен атрибут Qt::WA_DeleteOnClose
А еще я заметила, что если раскомментировать в деструктре QMessageBox , то все  в процессах удаляется почему-то


Название: Re: как организовать закрытие формы,если в ней были открыты другие формы
Отправлено: spectre71 от Июль 15, 2009, 11:17
Да,но тогда в таком случае выскакивает системная ошибка :(((, т.к. в таком случае вызываются 2 деструктора...у меня же установлен атрибут Qt::WA_DeleteOnClose
А еще я заметила, что если раскомментировать в деструктре QMessageBox , то все  в процессах удаляется почему-то
Так убери этот атрибут


Название: Re: как организовать закрытие формы,если в ней были открыты другие формы
Отправлено: Evgeniya от Июль 15, 2009, 11:23
Так он мне нужен...Мне нужно, чтобы при закрытии главной формы закрывалась и дочерняя


Название: Re: как организовать закрытие формы,если в ней были открыты другие формы
Отправлено: Авварон от Июль 15, 2009, 11:37
cоедини слот close() у главной формы со слотом quit() у QApplication'а. всё


Название: Re: как организовать закрытие формы,если в ней были открыты другие формы
Отправлено: Evgeniya от Июль 15, 2009, 12:44
cоедини слот close() у главной формы со слотом quit() у QApplication'а. всё

это в функции main нужно соединить???т.е. написать
QObject::connect(&w,SLOT(close()),&a,SLOT(quit()));

Я правильно понимаю??
такое ощущене, что программа вообще не реагирует на этот connect, видимо не правильно написала ;((


Название: Re: как организовать закрытие формы,если в ней были открыты другие формы
Отправлено: developer от Июль 15, 2009, 12:45
в свое время у меня тоже была данная проблема. Решыл ее следующим образом.
Припустим у меня есть три класса с формами: Form1, Form2, Form3.
Делаю класс
VerySeriousClass:
{
Form1* f1;
Form2* f2:
Form3* f3;
QMap<int, QWidget> globalmap;
}
Создаю динамически все три формы и запихиваю их в словарь globalmap:
globalmap[1] = new Form1;
globalmap[2] = new Form2;
globalmap[3] = new Form3;

Каждая форма должна иметь свой деструктор, или нужно обеспечить ее корректное  удаление.
После использования всех форм я просто удаляю globalmap. И еще для показа форм я использую show() когда нужно,  hide() когда нуно форму скрить. И перехвачиваю евент close() той формы, после которой нужно удалить  globalmap - то-есть закрить все формы.


Название: Re: как организовать закрытие формы,если в ней были открыты другие формы
Отправлено: Авварон от Июль 15, 2009, 12:56
оговорился, не слот а конечно сигнал закрытия, сейчас гляну как точно зовется
added: ойоой я наврал( не делай как я говорю:)
added2: можно попробовать соединить сигнал void destroyed ( QObject * obj = 0 ) и слот quit(), но не факт что форма дестроится


Название: Re: как организовать закрытие формы,если в ней были открыты другие формы
Отправлено: spectre71 от Июль 15, 2009, 12:58
Так он мне нужен...Мне нужно, чтобы при закрытии главной формы закрывалась и дочерняя
Qt::WA_DeleteOnClose никак не связан с закрытием дочерних окон!!!


Название: Re: как организовать закрытие формы,если в ней были открыты другие формы
Отправлено: Evgeniya от Июль 15, 2009, 13:10
Так он мне нужен...Мне нужно, чтобы при закрытии главной формы закрывалась и дочерняя
Qt::WA_DeleteOnClose никак не связан с закрытием дочерних окон!!!

просто при установленном свйстве Qt::WA_DeleteOnClose при закрытии объект удаляется и следовательно удаляет дочерние объекты...и получается, что при закрытии главной дочерняя-то закрывается, только вот  в процессах  экзешник остается


Название: Re: как организовать закрытие формы,если в ней были открыты другие формы
Отправлено: spirit от Июль 15, 2009, 13:10
Так он мне нужен...Мне нужно, чтобы при закрытии главной формы закрывалась и дочерняя
Qt::WA_DeleteOnClose никак не связан с закрытием дочерних окон!!!
м... это почему? если этот атрибут установлен для парента, а вся иерархия детей построена на паренте (т.е. задан парент для каждого ребенка),
то при закрытии парента (последует его удаление благодаря Qt::WA_DeleteOnClose) все дети будут уничтожены.


Название: Re: как организовать закрытие формы,если в ней были открыты другие формы
Отправлено: Evgeniya от Июль 15, 2009, 13:19
м... это почему? если этот атрибут установлен для парента, а вся иерархия детей построена на паренте (т.е. задан парент для каждого ребенка),
то при закрытии парента (последует его удаление благодаря Qt::WA_DeleteOnClose) все дети будут уничтожены.

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


Название: Re: как организовать закрытие формы,если в ней были открыты другие формы
Отправлено: Авварон от Июль 15, 2009, 13:21
причем тут деструкторы форм? напиши
int a = app.exec();
qDebug() << "вротмненоги";
return a;

если в консоль по закрытии окон пишется "вротмненоги", значит все ок, и НЕ гляди в диспетчер задач убогой винды


Название: Re: как организовать закрытие формы,если в ней были открыты другие формы
Отправлено: Evgeniya от Июль 15, 2009, 13:42
если в консоль по закрытии окон пишется "вротмненоги", значит все ок, и НЕ гляди в диспетчер задач убогой винды

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


Название: Re: как организовать закрытие формы,если в ней были открыты другие формы
Отправлено: spectre71 от Июль 15, 2009, 13:44
Я уже писал
Код
C++ (Qt)
int main(int argc, char *argv[])
{
   QApplication a(argc, argv);
   main_form w;
   w.show();
   return a.exec();
}
И не надо никаких Qt::WA_DeleteOnClose!
А на:
virtual void closeEvent(QCloseEvent *event);
Позакрывать все второстепенные окна!


Название: Re: как организовать закрытие формы,если в ней были открыты другие формы
Отправлено: spirit от Июль 15, 2009, 13:45
Я уже писал
Код
C++ (Qt)
int main(int argc, char *argv[])
{
   QApplication a(argc, argv);
   main_form w;
   w.show();
   return a.exec();
}
И не надо никаких Qt::WA_DeleteOnClose!
А на:
virtual void closeEvent(QCloseEvent *event);
Позакрывать все второстепенные окна!
результат будет такимже, писанины меньше.


Название: Re: как организовать закрытие формы,если в ней были открыты другие формы
Отправлено: spectre71 от Июль 15, 2009, 13:50
Можно еще использовать
void QApplication::closeAllWindows ()   [static slot]


Название: Re: как организовать закрытие формы,если в ней были открыты другие формы
Отправлено: Evgeniya от Июль 15, 2009, 14:00
Ну да, видимо так действительно проще будет сделать...
Только если у меня не одна форма, а 4, то в каждой нужно будет перегружать эту функцию...
А можно как-нибудь узать было-ли окно открыто, т.е.создан класс???


Название: Re: как организовать закрытие формы,если в ней были открыты другие формы
Отправлено: spectre71 от Июль 15, 2009, 14:03
Ну да, видимо так действительно проще будет сделать...
Только если у меня не одна форма, а 4, то в каждой нужно будет перегружать эту функцию...
А можно как-нибудь узать было-ли окно открыто, т.е.создан класс???
Создан - Указатель не NULL;
открыто - isVisible ()


Название: Re: как организовать закрытие формы,если в ней были открыты другие формы
Отправлено: Evgeniya от Июль 15, 2009, 14:58
Создан - Указатель не NULL;
открыто - isVisible ()
А если класс не был создан, то как проверить??


Название: Re: как организовать закрытие формы,если в ней были открыты другие формы
Отправлено: Авварон от Июль 15, 2009, 15:07
указатель == NULL?


Название: Re: как организовать закрытие формы,если в ней были открыты другие формы
Отправлено: spectre71 от Июль 15, 2009, 15:09
А если класс не был создан, то как проверить??
:D :D :D


Название: Re: как организовать закрытие формы,если в ней были открыты другие формы
Отправлено: Evgeniya от Июль 16, 2009, 08:42
т.е. когда я объявляю указатель, doch *t и до его определения t=new doch(this);t->show(); , получается что t==NULL??Я правильно понимаю???просто у меня так не получается... :-[


Название: Re: как организовать закрытие формы,если в ней были открыты другие формы
Отправлено: spirit от Июль 16, 2009, 08:48
нет, если ты объявляешь таким образом doch *t; то нет ни какой гарантии (все зависит от компилятора), что указатель нулевой.
нужно явно инициализировать его нулем doch *t = 0;.
либо же использовать QPointer в таком виде QPointer<doch> t;.


Название: Re: как организовать закрытие формы,если в ней были открыты другие формы
Отправлено: Авварон от Июль 16, 2009, 08:56
кстати я могу ошибасться, но вроде в с++ для всех переменных зовутся конструкторы по умолчанию, в тч для встроеных типов - как раз зануление их, нет? баги с неинициализированными переменными были в си, а вот в с++ никогда такого не встречал (в gcc)


Название: Re: как организовать закрытие формы,если в ней были открыты другие формы
Отправлено: Evgeniya от Июль 16, 2009, 09:00
Спасибочки, теперь все понятно...
Всем,всем,всем огромное СПАСИБО!!!!!


Название: Re: как организовать закрытие формы,если в ней были открыты другие формы
Отправлено: Evgeniya от Июль 16, 2009, 09:02
кстати я могу ошибасться, но вроде в с++ для всех переменных зовутся конструкторы по умолчанию, в тч для встроеных типов - как раз зануление их, нет? баги с неинициализированными переменными были в си, а вот в с++ никогда такого не встречал (в gcc)
У меня не зануляется...


Название: Re: как организовать закрытие формы,если в ней были открыты другие формы
Отправлено: spirit от Июль 16, 2009, 09:06
кстати я могу ошибасться, но вроде в с++ для всех переменных зовутся конструкторы по умолчанию, в тч для встроеных типов - как раз зануление их, нет? баги с неинициализированными переменными были в си, а вот в с++ никогда такого не встречал (в gcc)
еще раз повторяю, все зависит от компилятора, например в студии выхеуказанный вызывов не инициализирует переменную нулем -- в ней мусор.
и вообще -- это плохой стиль не инициализировать переменные и пологаться на компилятор.