MDI & QT best practices
От: Stanislav V. Zudin Россия  
Дата: 18.08.11 06:46
Оценка:
Здравствуйте,
ищу совет, как правильно готовить MDI на QT.
Т.к. до сих пор работал с голым WinAPI, MFC и WTL, то QT выглядит несколько диковато.

Для начала, как работать с меню (menuBar)? Есть ли возможность загрузить меню целиком? Или сборка из отдельных элементов в рантайме это нормальная практика?

Применительно к MDI, если имеем несколько документов разного типа (например текстовый редактор и графический), как переключать меню при смене активного документа? Убивать все содержимое menuBar'а и лепить заново? Или есть метод поизящнее?

Собственно, те же вопросы и по использованию QAction.

Принято делать так?

    saveAct = new QAction(QIcon(":/images/save.png"), tr("&Save..."), this);
    saveAct->setShortcuts(QKeySequence::Save);
    saveAct->setStatusTip(tr("Save the current form letter"));
    connect(saveAct, SIGNAL(triggered()), this, SLOT(save()));

    printAct = new QAction(QIcon(":/images/print.png"), tr("&Print..."), this);
    printAct->setShortcuts(QKeySequence::Print);
    printAct->setStatusTip(tr("Print the current form letter"));
    connect(printAct, SIGNAL(triggered()), this, SLOT(print()));

    ... еще много-много раз...


Или есть какие-то средства "автоматизации", не упомянутые в примерах? Типа карт сообщений в WTL/MFC? Пока, кроме изобретения собственного велосипеда, ничего не нашел.

Если разные документы должны обрабатывать одну и ту же команду, например "Печать", где принято создавать соответствующий QAction?
В MainWindow? А как тогда передать обработку активному документу (использовать грядку из qobject_cast'ов)?
Или же создавать в каждом документе свою копию QAction'а? Не будут ли они конфликтовать в этом случае?
_____________________
С уважением,
Stanislav V. Zudin
Re: MDI & QT best practices
От: MTD https://github.com/mtrempoltsev
Дата: 04.04.12 10:43
Оценка: 8 (1)
Здравствуйте, Stanislav V. Zudin, Вы писали:

SVZ>Для начала, как работать с меню (menuBar)? Есть ли возможность загрузить меню целиком? Или сборка из отдельных элементов в рантайме это нормальная практика?


Да, это нормальная практика. Что не устраивает?

SVZ>Применительно к MDI, если имеем несколько документов разного типа (например текстовый редактор и графический), как переключать меню при смене активного документа? Убивать все содержимое menuBar'а и лепить заново?


Нормальный вариант.

SVZ>Собственно, те же вопросы и по использованию QAction.


SVZ>Принято делать так?


Да.

SVZ>Или есть какие-то средства "автоматизации", не упомянутые в примерах? Типа карт сообщений в WTL/MFC?


Не в курсе, что это. Покажи, что хочется.

SVZ>Если разные документы должны обрабатывать одну и ту же команду, например "Печать", где принято создавать соответствующий QAction?

SVZ>В MainWindow? А как тогда передать обработку активному документу (использовать грядку из qobject_cast'ов)?
SVZ>Или же создавать в каждом документе свою копию QAction'а? Не будут ли они конфликтовать в этом случае?

Это не имеет отношения к Qt — это вопрос к дизайну. Пример:

class AbstractData
{
   virtual void Print() = 0;
};

void printAction()
{
   CurrentData_->Print();
}
Re[2]: MDI & QT best practices
От: Stanislav V. Zudin Россия  
Дата: 04.04.12 11:08
Оценка:
Здравствуйте, MTD, Вы писали:


MTD>Здравствуйте, Stanislav V. Zudin, Вы писали:


SVZ>>Для начала, как работать с меню (menuBar)? Есть ли возможность загрузить меню целиком? Или сборка из отдельных элементов в рантайме это нормальная практика?


MTD>Да, это нормальная практика. Что не устраивает?

Получается очень большой объем ручной работы. Ну и приходится создавать невероятную прорву QAction.
Кроме того, у меня сложилось впечатление, что в QT MDI не очень поощряется, особенно с разнотипными документами, что требуется мне.

SVZ>>Или есть какие-то средства "автоматизации", не упомянутые в примерах? Типа карт сообщений в WTL/MFC?


MTD>Не в курсе, что это. Покажи, что хочется.


В WinAPI/MFC/WTL команда от тулбара или меню идентифицируется числовым идентификатором, который передается в виндовом сообщении WM_COMMAND.
Поэтому все команды легко свести к массиву/мапу указателей на интерфейсы или функции. При этом легко гонять все команды от одного обработчика к другому.
Например, в MFC команду можно обработать во вьюшке, Документе, главном окне приложения — сообщение передается по цепочке, пока кто-нибудь его не обработает.
Если в определенный момент желающих обработать не найдется, то ничего криминального не произойдет — команда похерится.

SVZ>>Если разные документы должны обрабатывать одну и ту же команду, например "Печать", где принято создавать соответствующий QAction?

SVZ>>В MainWindow? А как тогда передать обработку активному документу (использовать грядку из qobject_cast'ов)?
SVZ>>Или же создавать в каждом документе свою копию QAction'а? Не будут ли они конфликтовать в этом случае?

MTD>Это не имеет отношения к Qt — это вопрос к дизайну. Пример:


MTD>
MTD>class AbstractData
MTD>{
MTD>   virtual void Print() = 0;
MTD>};

MTD>void printAction()
MTD>{
MTD>   CurrentData_->Print();
MTD>}
MTD>


Да, я думал про такое. Потому и решил спросить тех, кто использует QT в боевых условиях, что есть в фреймворке для решения моей задачи.
Оказалось, готовых решений нет и надо городить свой велосипед.

Спасибо тебе за разъяснения.
_____________________
С уважением,
Stanislav V. Zudin
Re[3]: MDI & QT best practices
От: MTD https://github.com/mtrempoltsev
Дата: 04.04.12 11:25
Оценка:
Здравствуйте, Stanislav V. Zudin, Вы писали:

MTD>>Да, это нормальная практика. Что не устраивает?

SVZ>Получается очень большой объем ручной работы. Ну и приходится создавать невероятную прорву QAction.

Тут без вариантов — в любом фреймворке надо описать, что тебе надо. Как без этого? С QAction — это очень удобно, ведь его можно вставить не только в основное меню, но и например в меню показываемое по правой кнопке.

SVZ>В WinAPI/MFC/WTL команда от тулбара или меню идентифицируется числовым идентификатором, который передается в виндовом сообщении WM_COMMAND.

SVZ>Поэтому все команды легко свести к массиву/мапу указателей на интерфейсы или функции. При этом легко гонять все команды от одного обработчика к другому.
SVZ>Например, в MFC команду можно обработать во вьюшке, Документе, главном окне приложения — сообщение передается по цепочке, пока кто-нибудь его не обработает.

Вообще не понял нафига лезть под капот?

SVZ>Если в определенный момент желающих обработать не найдется, то ничего криминального не произойдет — команда похерится.


Это вообще печально.

Короче, вот пример в псевдокоде:


MainWindow()
{
   CreateActions();
   CurrentData_ = new TxtData();
   setMenuBar(CreateMenu(CurrentData_));
}

CreateActions()
{
   Open_ = new QAction();
   Print_ = new QAction();
}

CreateMenu(TxtData&)
{
   QMenuBar* menu = new QMenuBar();
   menu->addAction(Open_);
   menu->addAction(Print_);
   return menu;
}

CreateMenu(BinData&)
{
   QMenuBar* menu = new QMenuBar();
   menu->addAction(Open_);
   return menu;
}

Open()
{
   CurrentData_->Open();
}


SVZ>Да, я думал про такое. Потому и решил спросить тех, кто использует QT в боевых условиях, что есть в фреймворке для решения моей задачи.

SVZ>Оказалось, готовых решений нет и надо городить свой велосипед.

Для всего на свете решений нет нигде.
Re[4]: MDI & QT best practices
От: Stanislav V. Zudin Россия  
Дата: 04.04.12 11:45
Оценка:
Здравствуйте, MTD, Вы писали:

SVZ>>В WinAPI/MFC/WTL команда от тулбара или меню идентифицируется числовым идентификатором, который передается в виндовом сообщении WM_COMMAND.

SVZ>>Поэтому все команды легко свести к массиву/мапу указателей на интерфейсы или функции. При этом легко гонять все команды от одного обработчика к другому.
SVZ>>Например, в MFC команду можно обработать во вьюшке, Документе, главном окне приложения — сообщение передается по цепочке, пока кто-нибудь его не обработает.

MTD>Вообще не понял нафига лезть под капот?


Ну я бы не назвал это лазаньем под капот
Есть команды разной породы:
Всякие Open, Exit, Settings etc. — они не зависят от текущего документа и могут обрабатываться в главном окошке, ни один документ о них и знать не знает.
Есть команды, специфичные для текущего документа, их обработчики находятся в соответствующих документах. Та же команда Print может поддерживаться всеми типами документов, но будет обработана только текущим документом.
А есть команды, которые относятся даже не к документу, а к его, активной в данный момент, вьюшке (масштабирование изображения, к примеру). Обработчики этих команд будут находиться, соответственно, во вьюхе.
Но ходить все команды будут по одному маршруту, их легко можно поймать и обработать. Или перехватить, что-то сделать свое, а потом дать команде долететь до цели.

Т.е. получается-то фактически то же, что ты нарисовал в примере, но на другом уровне.

MTD>Короче, вот пример в псевдокоде:


(пример скипнул) Примерно так же и стал делать, но были сомнения.
_____________________
С уважением,
Stanislav V. Zudin
Re[3]: MDI & QT best practices
От: Kswapd Россия  
Дата: 04.04.12 18:34
Оценка:
SVZ>Получается очень большой объем ручной работы. Ну и приходится создавать невероятную прорву QAction.

Можно описать меню на подходящем DSL и генерировать по описанию. Заодно появляется возможность кастомизации меню юзером — мелочь, а приятно.
Re: MDI & QT best practices
От: Аноним  
Дата: 04.04.12 18:55
Оценка:
SVZ>Пока, кроме изобретения собственного велосипеда, ничего не нашел.

IMHO. КуТэ низкоуровневый фрэймворк заточенный не для написания сложных приложений, а для абстрагирования ГУИ. Все плюшки придется писать или дописывать вручную.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.