crossplatform.ru

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

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


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

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

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




Репутация:   94  


Цитата(mva @ 18.3.2010, 20:46) *
Код довольно сложный. Готовы ли Вы разбираться в нем?
вот избавься от сложного кода и точно всё встанет на свои места.
В сообщении №2 я показал как должен выглядеть код, для случая с наследованием от QWidget. Примерно такой же код я и хотел бы увидеть.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
mva
  опции профиля:
сообщение 18.3.2010, 19:10
Сообщение #12


Участник
**

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

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




Репутация:   0  


Вот так примерно выглядят классы, которые работают в данном контексте:

CODE


class Form: public QDialog {
// Класс формы обеспечивает базовый функционал для всех форм приложения (кнопки "Принять", "Отменить"; сохранение конфигурации окна и т.п.)

Q_OBJECT

public:
Form(QWidget* pwgt = 0, Essence* par = 0);
...
public slots:
int exec() { return doExec(); }
void show() { doShow(); }
...
protected:
QMdiSubWindow* mdiSubWindow;
Essence* parent;
virtual int doExec();
virtual void doShow();
...
};


Form::Form(QWidget* pwgt, Essence* par):QDialog(pwgt, Qt::WindowTitleHint) {
parent = par;
...
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();
}

//----------------------------------------------------------------------------------------
class FormGrid : public Form {
// Класс обеспечивает функционал для форм, имеющих Grid (кнопки "Добавить", "Удалить", "Просмотреть", "Обновить", "Печать") плюс базовый функционал класса Form
...
};

//----------------------------------------------------------------------------------------
class FormGridSearch : public FormGrid {
// Класс обеспечивает функционал для форм, имеющих Grid и параметры для поиска (например для просмотра сущности "Справочник")
...
};

//----------------------------------------------------------------------------------------
class FormDocument : public FormGrid {
// Класс обеспечивает функционал для просмотра содержимого документа
...
};

//----------------------------------------------------------------------------------------
class Essence {
// Класс, который описывает базовый функционал сущностей предметной области (справочники, документы, списки документов, отчеты и т.п.)
...
virtual int exec();
virtual void show();
...
protected:
FormGrid* form;
...
virtual void setForm(); // Чисто виртуальная функция. Переопределяется в подклассах
...
};

int Essence::exec() {
return form->exec();
}

void Essence::show() {
form->show();
}

//----------------------------------------------------------------------------------------
class Dictionary : public Essence {
// Класс описывает сущность "Справочник"
public:
...
protected:
...
virtual void setForm();
...
};

void Dictionary::setForm() {
form = new FormGridSearch((QWidget*)app->getMainWindow(), this);
}

//----------------------------------------------------------------------------------------

class Document : public Essence {
// Класс сущности "Документ"
public:
QMap<QString, Dictionary*> dictionaries; // Объекты справочников, которыми оперирует документ
...
virtual bool add(); // Функция добавляет новую строку в документ
...
protected:
virtual void setForm(); // Устанавливает соответствующую сущньсти "Документ" форму
private:
...
bool showNextDict(); // Производит перебор справочников при добавлении новой строки
...
};

bool Document::add() {
...
if (showNextDict()) {
...
return true;
}
return false;
}

void Document::setForm() {
form = new FormDocument((QWidget*)parentForm, this);
}

bool Document::showNextDict() {
Dictionary* dict;
bool anyShown = true;
foreach (QString dictName, dictionaries.keys()) {
dict = dictionaries.value(dictName);
if (...) {
dict->exec(); // Показать справочник в модальном окне. Пользователь должен выбрать объект справочника, прежде чем двигаться дальше
...
if (dict->isFormSelected()) {
if (...) {
anyShown = false; // то считать, что этот справочник не был показан и не давать добавить строчку в документ
break;
}
}
else {
anyShown = false; // пользователь отказался от работы со справочниками. Прекратим процесс добавления записи
break;
}
}
}
return anyShown;
}



После инициализации всех объектов действия начинаются с вызова функции Docement::add() - добавление новой строки в документ.


Цитата(Litkevich Yuriy @ 18.3.2010, 17:51) *
вот избавься от сложного кода и точно всё встанет на свои места.
В сообщении №2 я показал как должен выглядеть код, для случая с наследованием от QWidget. Примерно такой же код я и хотел бы увидеть.


Если для каждого вида окна писать собственный код, то может быть и можно упростить код для каждого по отдельности окна, но не для приложения в целом, если таких окон в приложении множество. Я пытаюсь классифицировать окна по их назначению и внешнему виду и выделить общие свойства в соответствующих классах. Например так:

Form - Пустое окно и кнопки "Принять", "Отменить". Запоминает размеры окна.
FormGrid::Form - Окно с кнопками "Принять", "Отменить", плюс кнопки "Добавить", "Удалить", "Просмотреть", "Обновить", "Печать", плюс просмотр таблиц (для сущностей "Отчет", "Список документов" и т.п.)
FormGridSearch::FormGrid::Form - Окно со всеми кнопками и Grid, плюс возможность настройки фильтров поиска (для сущностей типа "Справочник")

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

Если присмотреться, мой кусок кода, который работает с QMdiSubWindow, похож на Ваш.


Я поторопился. Не совсем похож.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 18.3.2010, 20:31
Сообщение #13


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

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

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




Репутация:   94  


Цитата(mva @ 18.3.2010, 22:10) *
Вот так примерно выглядят классы
посмотри внимательно на сообщение №2.
Там, в главном окне (!) создаётся субокно, а не внутри класса описывающего субокно
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
mva
  опции профиля:
сообщение 19.3.2010, 11:07
Сообщение #14


Участник
**

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

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




Репутация:   0  


Цитата(Litkevich Yuriy @ 18.3.2010, 20:31) *
посмотри внимательно на сообщение №2.
Там, в главном окне (!) создаётся субокно, а не внутри класса описывающего субокно


Сделал класс Form наследуемым от QWidget, а не от QDialog. Конструктор класса Form подправил вот так:
CODE

Form::Form(QWidget* pwgt, Essence* par):QWidget(pwgt, Qt::WindowTitleHint) {

parent = par;

...

// mdiSubWindow = app->getMainWindow()->getWorkspace()->addSubWindow(this, Qt::Window);
// mdiSubWindow->setAttribute(Qt::WA_DeleteOnClose, false);
// mdiSubWindow->setVisible(false);

mdiSubWindow = new QMdiSubWindow;
mdiSubWindow->setWidget(this);
mdiSubWindow->setAttribute(Qt::WA_DeleteOnClose);
mdiSubWindow = app->getMainWindow()->getWorkspace()->addSubWindow(mdiSubWindow, Qt::Window);
}

Думаю, что это то, что вы предлагаете.

В результате приложение стало выглядеть так:


А должно выглядеть так:



Кстати, я попробовал сделать окна в примере /qt/examples/mainwindows/mdi, который идет в комплекте с Qt4, модальными. Я добавил лишь одну строку в реализации процедуры MainWindow::newFile():
CODE

void MainWindow::newFile()
{
MdiChild *child = createMdiChild();
child->newFile();
child->setWindowModality(Qt::WindowModal); // эта строка добавлена мной
child->show();
}

В результате это приложение стало тоже зацикливаться при открытии нового окна. Оно перестает реагировать на любые события и выйти из него можно только путем снятия процесса.
Почему в этом примере не удалось сделать окна модальными?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 19.3.2010, 13:20
Сообщение #15


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

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

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




Репутация:   94  


Цитата(mva @ 19.3.2010, 14:07) *
Думаю, что это то, что вы предлагаете.
нет, в виджете, нет никаких QMdiSubWindow, WA_DeleteOnClose, ... Он о их существовании вообще ничего не знает, это нужно делать снаружи.
Ну и при наследовании от QWidget, не забыть определить методы, которыми пользуются компоновщики (sizeHint, ...)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

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


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




RSS Текстовая версия Сейчас: 30.11.2024, 6:35