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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: Удаление динамических окон QFrame  (Прочитано 6692 раз)
Keeper_B
Гость
« : Марта 07, 2010, 16:15 »

Поискал  на форуме, но ничего подобного не нашёл.

Есть главное окно MainWindow, а в нём при нажатии на кнопки появляются различные окна QFrame.
Вопрос как их удалять, при вызове close(), если они динамические?
Внизу пример с одним динамическим окном QFrame.

Думаю приводить код самого удаляемого окна смысла нет, внизу код главного окна, в котором надо удалять дочерние window.

Вот mainwindows.h
Код
C++ (Qt)
class MainWindow : public QMainWindow {
   Q_OBJECT
public:
   MainWindow(QWidget *parent = 0);
   ~MainWindow();
 
protected:
   void changeEvent(QEvent *e);
 
private:
Ui::MainWindow *ui;
QFrame* Window;
 
private slots:
void AboutProgramm();
void newWindow();
};
 

А вот mainwindow.cpp
Код
C++ (Qt)
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow),
Window(0)
{
ui->setupUi(this);
 
connect(ui->actionExit, SIGNAL(activated()), qApp, SLOT(quit()));
connect(ui->actionAbout_Qt, SIGNAL(activated()), qApp, SLOT(aboutQt()));
connect(ui->actionAbout, SIGNAL(activated()), this, SLOT(AboutProgramm()));
connect(ui->actionOpen, SIGNAL(activated()), this, SLOT(newWindow()));
}
 
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::AboutProgramm()
{
AboutDialog about(this);
about.exec();
 
// AboutDialog *about = new AboutDialog(this);
// about->exec();
// delete about;
}
 
void MainWindow::newWindow()
{
if (!Window) {
Window = new QFrame(this);
ui->statusBar->showMessage("new window");
}
else
ui->statusBar->showMessage("old window");
 
Window->show();
Window->activateWindow();
}
 

« Последнее редактирование: Марта 07, 2010, 17:39 от Keeper_B » Записан
alexman
Гость
« Ответ #1 : Марта 07, 2010, 17:01 »

Можно хранить указатель на QFrame в главном окне, а в конструкторе главного окна создать QFrame и в качестве родителя указать главное окно, а далее об удалении не нужно думать!
Записан
SABROG
Гость
« Ответ #2 : Марта 07, 2010, 17:23 »

Код
C++ (Qt)
Window = new CDFrame(this);
Window->setAttribute(Qt::WA_DeleteOnClose);
 
Записан
Keeper_B
Гость
« Ответ #3 : Марта 07, 2010, 17:38 »

Код
C++ (Qt)
Window = new QFrame(this);
Window->setAttribute(Qt::WA_DeleteOnClose);
 

Я пробовал с этим WA_DeleteOnClose, он вылетает при повторном открытии окна Window.
Записан
Keeper_B
Гость
« Ответ #4 : Марта 07, 2010, 17:47 »

Можно хранить указатель на QFrame в главном окне, а в конструкторе главного окна создать QFrame и в качестве родителя указать главное окно, а далее об удалении не нужно думать!

Не совсем понял мысль.

>Можно хранить указатель на QFrame в главном окне
так у меня указатель там вроде и хранится.
Вот же    QFrame* Window;

>а в конструкторе главного окна создать QFrame и в качестве родителя указать главное окно
Так этож получится, что окно будет постоянно в памяти.
А у меня весь цимес в том, что не держать дочерние окна постоянно в памяти, а создавать их по мере надобности.
Записан
SABROG
Гость
« Ответ #5 : Марта 07, 2010, 17:48 »

Я пробовал с этим WA_DeleteOnClose, он вылетает при повторном открытии окна Window.

А в первом посте сложно было об этом написать? Ты уж выбирай либо одно окно, которое создается один раз и умирает при закрытии приложения, либо каждый раз создавать новое (в этом случае проверку "if (!Window) {" можно убрать).

P.S.: пора бы уже знать, что в C++ удаление указателя не приводит к его обнулению.
Записан
BRE
Гость
« Ответ #6 : Марта 07, 2010, 17:49 »

Я пробовал с этим WA_DeleteOnClose, он вылетает при повторном открытии окна Window.
Конечно будет вылетать. Фрейм при закрытии разрушается, а указатель Window продолжает указывать на разрушенный объект.
Попробуй соединять сигнал destroyed объекта Window со своим слотом, который будет "занулять" переменную Window.
Записан
Keeper_B
Гость
« Ответ #7 : Марта 07, 2010, 17:53 »

Я пробовал с этим WA_DeleteOnClose, он вылетает при повторном открытии окна Window.

А в первом посте сложно было об этом написать? Ты уж выбирай либо одно окно, которое создается один раз и умирает при закрытии приложения, либо каждый раз создавать новое (в этом случае проверку "if (!Window) {" можно убрать).

P.S.: пора бы уже знать, что в C++ удаление указателя не приводит к его обнулению.

А, всё теперь ясно. Улыбающийся
Я просто не до конца понял, что именно делает WA_DeleteOnClose.


>пора бы уже знать, что в C++ удаление указателя не приводит к его обнулению.
Это я знаю Улыбающийся

« Последнее редактирование: Марта 07, 2010, 18:02 от Keeper_B » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #8 : Марта 07, 2010, 17:56 »

Указатель конечно нужно обнулять. Но можно обойтись и без указателя - напр. задав имя создаваемого QFrame (setObjectName) и проверять "уже создано" с помощью findChild
Записан
Keeper_B
Гость
« Ответ #9 : Марта 07, 2010, 19:19 »

Всем спасибо!
РЕШЕНО.
Записан
SABROG
Гость
« Ответ #10 : Марта 07, 2010, 19:30 »

Вообще с указателями на QObject'ы правильно так работать:

Код
C++ (Qt)
//header
private:
QWeakPointer<QFrame> frame;
...
Q_ASSERT(frame); // проверяем инициализирован ли объект (QWeakPointer) вообще каким либо указателем
QFrame* pFrame = frame.data();
   if (pFrame) { // проверяем не удален ли указатель
   ... // объект живой, делаем с ним чего-нибудь.
   }
 

С маленькой оговоркой - объект не должен удаляться в другом потоке/контексте. Как правило такое может возникнуть в следующей ситуации. QObject создавался в одном потоке, потом мы его переносим через QObject::moveToThread() в другой поток, затем вызываем delete. Тогда будет косяк. Такой объект правильно удалять через QObject::deleteLater(). Опять же если в этом потоке не вызывается exec(), который запускает обработку событий, то deleteLater() не удалит такой объект. То есть помимо обязательного deleteLater() в отдельном потоке вместо delete наличие вызова exec()/processEvents() также обязательно. Иначе нужно отказаться от удаления классов на базе QObject'a в отдельных потоках вообще. Можно конечно отказаться от QWeakPointer'a и использовать обычный указатель, который обнулять потом, обернув все это в мутекс, только это решение может иметь последствия, если тот же главный поток ждет сигнала destroyed(), например QObjectCleanupHandler(), который об этом никогда не узнает будучи ребенком другого потока.
« Последнее редактирование: Марта 07, 2010, 19:33 от SABROG » Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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