crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

2 страниц V   1 2 >  
Ответить в данную темуНачать новую тему
> Циклит QDialog::exec() в рамках QMdiArea
mva
  опции профиля:
сообщение 18.3.2010, 10:03
Сообщение #1


Участник
**

Группа: Участник
Сообщений: 104
Регистрация: 15.3.2009
Из: Киров
Пользователь №: 615

Спасибо сказали: 3 раз(а)




Репутация:   0  


Добрый день!

Я хочу создать класс окна, который может работать в рамках QMdiArea как простое окно и как модальное. Делаю я это так (если все представить упрощенно):

CODE


class Form: public QDialog {
Q_OBJECT
public:
Form(QWidget* pwgt = 0);
...
protected:
QMdiSubWindow* mdiSubWindow;
virtual int exec();
virtual void show();
...
};

Form::Form(QWidget* pwgt): QDialog(pwgt, Qt::WindowTitleHint) {
...
mdiSubWindow = app->getMainWindow()->getWorkspace()->addSubWindow(this, Qt::Window);
mdiSubWindow->setAttribute(Qt::WA_DeleteOnClose, false);
mdiSubWindow->setVisible(false);
}

int Form::exec() {
return QDialog::exec(); // Здесь программа зацикливается - создает локальный обработчик событий, которые не поступают
}

void Form::show() {
QDialog::show(); // Здесь программа нормально работает
}



Проблема в том, что если я вызываю Form.show(), то все работает нормально, а если вызываю Form.exec(), то программа начинает циклить, и не отвечает ни на клавиатуру, ни на мышь.

Что я делаю не так?

Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 18.3.2010, 10:36
Сообщение #2


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9668
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Цитата(mva @ 18.3.2010, 13:03) *
Что я делаю не так?
а каккой смысл в этих функциях:
Цитата(mva @ 18.3.2010, 13:03) *
int Form::exec() {
return QDialog::exec(); // Здесь программа зацикливается - создает локальный обработчик событий, которые не поступают
}

void Form::show() {
QDialog::show(); // Здесь программа нормально работает
}


Лучше сделать наследника от QWidget, тогда ты сможешь его применять, где угодно. В коде главного окна просто вызывай так:
     Form *form = new Form();
// как субокно
     QMdiSubWindow *subWindow = new QMdiSubWindow;
     subWindow->setWidget(form);
     subWindow->setAttribute(Qt::WA_DeleteOnClose);
     mdiArea->addSubWindow(subWindow);
// ...
// как диалог
     form->setWindowModality(Qt::WindowModal);
     form->show();
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
mva
  опции профиля:
сообщение 18.3.2010, 11:37
Сообщение #3


Участник
**

Группа: Участник
Сообщений: 104
Регистрация: 15.3.2009
Из: Киров
Пользователь №: 615

Спасибо сказали: 3 раз(а)




Репутация:   0  


Определенный смысл в этих функциях есть. Класс Form, который является подклассом QDialog, сам в свою очередь является базовым классом для нескольких подклассов (окон различного вида, но со схожими базовыми функциями). Мне хотелось бы сохранить некоторый функционал базового класса QDialog, в том числе функции exec() и show(), но в несколько модифицированном виде. То есть это лучше представить так:

CODE


int Form::exec() {
...
return QDialog::exec();
}

void Form::show() {
...
QDialog::show();
}


Я добавил многоточия, под которым кроется функционал, отличающий Form::show() или Form::exec() от их прототипов в QDialog. Вообще, здесь я выложил код в сильно упрощенном виде, убрав то, что не относится к сути проблемы, может быть по этому здесь может быть не понятна мотивация именно такого решения.

Т.к. архитектура программы (не маленькой) уже сложилась, мне хотелось бы разрешить данную проблему в рамках уже этой сложившейся архитектуры.

Добавлю, что раньше, без использования QMdiArea, программа работала, но каждое окно документа работало вне рамок главного окна приложения. Проблема появилась после перехода на использование QMdiArea.



Сообщение отредактировал mva - 18.3.2010, 12:05
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 18.3.2010, 13:15
Сообщение #4


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9668
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Цитата(mva @ 18.3.2010, 14:37) *
Form::show() или Form::exec()
вообще открытые члены в наследниках не принято скрывать.
Т.к. это нарушает интуитивность API.
Если у класса Base, есть октрытый член foo(), то применительно к наследнику руки потянутся его вызвать, ошибка при компиляции поставит человека в тупик

по поводу диалога в МДИ:
я на практике убедился, что почти всегда стоит делать окна, заранее не главные, наследниками QWidget, т.к. их мы можем поместить куда угодно, в том числе в наследник QDialog.

В МДИ, я думаю, возникают проблемы, связанные с тем, что QDialog - всегда окно верхнего уровня, а parent в нём - всего лишь способ центровки и владения (для последующего удаления объекта).

П.С. имеет смысл переписать этот виджет пока совсем плохо не стало.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
kwisp
  опции профиля:
сообщение 18.3.2010, 13:31
Сообщение #5


астарожна ынтжинэр
*****

Группа: Участник
Сообщений: 1404
Регистрация: 26.11.2008
Из: ТаганрогРодинаЧехова
Пользователь №: 435

Спасибо сказали: 113 раз(а)




Репутация:   23  


вопрос еще почему переопределяется show() && exec() в секции protected если это вообще открытые слоты, да еще и делаются виртуальными???
не понятна цель настолько хитрого заворота.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
mva
  опции профиля:
сообщение 18.3.2010, 14:02
Сообщение #6


Участник
**

Группа: Участник
Сообщений: 104
Регистрация: 15.3.2009
Из: Киров
Пользователь №: 615

Спасибо сказали: 3 раз(а)




Репутация:   0  


Цитата(kwisp @ 18.3.2010, 13:31) *
вопрос еще почему переопределяется show() && exec() в секции protected если это вообще открытые слоты, да еще и делаются виртуальными???
не понятна цель настолько хитрого заворота.


Потому что в оригинале эти функции называются doShow() и doExec() и переопределяются в наследуемых классах, а их вызов производится собственно публичными функциями show() и exec(), которые определены в базовом классе Form, но не переопределяются в наследуемых классах. Хотел упростить восприятие, но видимо наоборот усложнил. Будем считать, что я имею такой код:

CODE

class Form: public QDialog {
Q_OBJECT
public:
Form(QWidget* pwgt = 0);
int exec() { return doExec(); }
void show() { return doShow(); }
...
protected:
QMdiSubWindow* mdiSubWindow;
virtual int doExec();
virtual void doShow();
...
};

Form::Form(QWidget* pwgt): QDialog(pwgt, Qt::WindowTitleHint) {
...
mdiSubWindow = app->getMainWindow()->getWorkspace()->addSubWindow(this, Qt::Window);
mdiSubWindow->setAttribute(Qt::WA_DeleteOnClose, false);
mdiSubWindow->setVisible(false);
}

int Form::doExec() {
...
return QDialog::exec(); // Здесь программа зацикливается - создает локальный обработчик событий, которые не поступают
}

void Form::doShow() {
...
QDialog::show(); // Здесь программа нормально работает
}

Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
MoPDoBoPoT
  опции профиля:
сообщение 18.3.2010, 14:07
Сообщение #7


Участник
**

Группа: Участник
Сообщений: 172
Регистрация: 7.5.2009
Из: Москва
Пользователь №: 738

Спасибо сказали: 44 раз(а)




Репутация:   9  


Цитата(mva @ 18.3.2010, 11:37) *
Класс Form, который является подклассом QDialog, сам в свою очередь является базовым классом для нескольких подклассов (окон различного вида, но со схожими базовыми функциями). Мне хотелось бы сохранить некоторый функционал базового класса QDialog, в том числе функции exec() и show(), но в несколько модифицированном виде.

Может тогда лучше отнаследоваться от QMdiSubWindow (чтобы внутри QMdiArea "ездить"), и реализовать весь функционал QDialog'а (благо всего 5 функций, 5 слотов и 3 сигнала). Для exec() надо будет обзавестись своим QEventLoop, а в общем тебе помогут исходники QDialog'а и эта тема.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
mva
  опции профиля:
сообщение 18.3.2010, 14:09
Сообщение #8


Участник
**

Группа: Участник
Сообщений: 104
Регистрация: 15.3.2009
Из: Киров
Пользователь №: 615

Спасибо сказали: 3 раз(а)




Репутация:   0  


Цитата(Litkevich Yuriy @ 18.3.2010, 13:15) *
по поводу диалога в МДИ:
я на практике убедился, что почти всегда стоит делать окна, заранее не главные, наследниками QWidget, т.к. их мы можем поместить куда угодно, в том числе в наследник QDialog.

В МДИ, я думаю, возникают проблемы, связанные с тем, что QDialog - всегда окно верхнего уровня, а parent в нём - всего лишь способ центровки и владения (для последующего удаления объекта).

П.С. имеет смысл переписать этот виджет пока совсем плохо не стало.


Наверное стоит попробовать унаследовать Form от QWidget, а не от QDialog.
...
Попробовал. Все равно так же циклит.
...
Буду пробовать следующий вариант - наследовать Form от QMdiSubWindow.

Сообщение отредактировал mva - 18.3.2010, 14:26
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 18.3.2010, 15:21
Сообщение #9


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9668
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Цитата(mva @ 18.3.2010, 17:09) *
Буду пробовать следующий вариант - наследовать Form от QMdiSubWindow.
опять не унифицированный способ, тепрь ты сможешь использовать Form, только в узкой области - МДИ

Цитата(mva @ 18.3.2010, 17:09) *
Попробовал. Все равно так же циклит.
покажи код как ты создаёшь и вызываешь субокно/диалог
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
mva
  опции профиля:
сообщение 18.3.2010, 17:46
Сообщение #10


Участник
**

Группа: Участник
Сообщений: 104
Регистрация: 15.3.2009
Из: Киров
Пользователь №: 615

Спасибо сказали: 3 раз(а)




Репутация:   0  


Цитата(mva @ 18.3.2010, 14:09) *
Буду пробовать следующий вариант - наследовать Form от QMdiSubWindow.


Пока не прокатило... Требуются сложные переделки. По-простому не получилось.

Цитата(Litkevich Yuriy @ 18.3.2010, 15:21) *
покажи код как ты создаёшь и вызываешь субокно/диалог


Код довольно сложный. Готовы ли Вы разбираться в нем? Сегодня постараюсь подготовить. Выложу не весь, а только те куски кода, которые имеют отношение к проблеме.

Сообщение отредактировал mva - 18.3.2010, 17:46
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

2 страниц V   1 2 >
Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 24.10.2021, 3:50