Russian Qt Forum
Сентябрь 24, 2024, 12:14 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: пара вопросов по сигналам-слотам  (Прочитано 5734 раз)
Гурман
Гуру общения
******
Offline Offline

Сообщений: 1442

Qt 2.2, 3.3, 4.5, 4,7, 4.8, 5.3, 5.6, 5.9, 5.12


Просмотр профиля
« : Апрель 05, 2010, 08:38 »

делаем контекстно зависимое меню, очень зависимое, некоторые пункты могут не отображаться, некоторые постоянные, наиболее простой вариант: создать меню заранее, потом при входе в его PopUpContextMenu(), сначала его clear(), затем в зависимости от контекста, заполняем его соответствующими addAction(), и сразу для каждой акции connect() на слот обработки команды

вопрос 1 - при выполнении clear что происходит с коннектами? они корректно отключаются? не надо специально делать disconnect() для всех соединений? насколько я понял, clear() удаляет инстансы всех объектов action, следовательно, должен и разрывать соединения, во всяком случае, никаких побочных эффектов пока не видно, но мало ли - вдруг из-за этого будет memory leak какой-нибудь

в общем, кто это хорошо изучил уже? подскажите...

вопрос 2 - из Qt Internals и ранее известно, что SLOT() это вообще-то указатель на символную строку, ака const char* - но мало ли, вдруг потом в дизайне Qt изменится что-нибудь, и это будет уже другой тип данных, нет ли какого-нибудь неописанного макро, которое можно использовать для объявления параметров функции, если ей надо передать SLOT()? то есть, написал я такой метод:

Код:
void MainWindow::addMenu( char* name, const char* slot )
{
QAction* action = new QAction(tr( name ) );
        if( action )
        {
       contextMenu->addAction( action ,contextMenu) );
       connect( action, SIGNAL(triggered()), this, slot );
        }
}

и вызываю его примерно так при формировании пунктов меню:

Код:
	...	
                case OVERWORD:
addMenu( "Копировать", SLOT(slotCopy()) );
addMenu( "Вставить", SLOT(slotPaste()) );
addMenu( "Вырезать", SLOT(slotCut()) );
addMenu( "Удалить", SLOT(slotDelete()) );
                ...

может правильнее было бы не const char* параметр у addMenu объявить, а иначе, может специальное макро есть?
Записан

2^7-1 == 127, задумайтесь...
voronElf
Гость
« Ответ #1 : Апрель 05, 2010, 09:00 »

1. насколько понимаю, при удалении объекта все его коннекты удаляются валидно, ничего самому делать не нужно.

2. не связывал так никогда, так что ничего про подобный макрос не знаю. Но даже если чтото и "изменится в дизайне Qt" (что ?) то поддержка старых версий все равно останется (на крайняк создадут механизм перехода с версии на версию).
Записан
Makss
Гость
« Ответ #2 : Апрель 05, 2010, 09:37 »

Делать clear() незачем!!!

просто делайте те акшины которые не должны показываться - невидимыми.
метод - setVisible(bool).

тем самым даже задумываться о connect и disconnect ненада...
Записан
Гурман
Гуру общения
******
Offline Offline

Сообщений: 1442

Qt 2.2, 3.3, 4.5, 4,7, 4.8, 5.3, 5.6, 5.9, 5.12


Просмотр профиля
« Ответ #3 : Апрель 05, 2010, 09:59 »

ой не... там десятка полтора видов контекста, очень сильно разное меню, с addSeparator() в самых разных местах

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

2^7-1 == 127, задумайтесь...
whirlwind
Гость
« Ответ #4 : Апрель 05, 2010, 10:11 »

QActions, добавленные к QMenu, не удаляются при разрушении меню. Поэтому собственно меню можно создавать прямо в обработкике евента и заполнять так, как хочется. А actions создать и хранить отдельно.
Так в application example сделано:
Код:
 void MainWindow::contextMenuEvent(QContextMenuEvent *event)
 {
     QMenu menu(this);
     menu.addAction(cutAct);
     menu.addAction(copyAct);
     menu.addAction(pasteAct);
     menu.exec(event->globalPos());
 }


Записан
mkv
Гость
« Ответ #5 : Апрель 05, 2010, 10:17 »

2. вы используете макрос SLOT - это и есть некоторая гарантия, что в будущих версиях это будет работать...
сейчас SLOT разворачиватся, например для SLOT(slotCopy()), в 1slotCopy()...
т.е. просто довавляет 1 или 2 в зависимости от того что это, слот или сигнал...
если они захотят изменить это, то изменят макросы....
Записан
Гурман
Гуру общения
******
Offline Offline

Сообщений: 1442

Qt 2.2, 3.3, 4.5, 4,7, 4.8, 5.3, 5.6, 5.9, 5.12


Просмотр профиля
« Ответ #6 : Апрель 05, 2010, 10:25 »

QActions, добавленные к QMenu, не удаляются при разрушении меню.

это точно??

QMenu это QWidget, и метод addAction() у него от виджета

а про QWidget написано:

Код:
QWidget::~QWidget ()

Destroys the widget.

[b]All this widget's children are deleted first.[/b]

правда в addAction()

Цитировать
The ownership of action is not transferred to this QWidget.

но в то же время, я при создании каждого QAction осознанно передаю указатель на QMenu, как на родителя - соответственно, при удалении родительского виджета должны удалиться все его дети

вопрос не праздный, мне надо убедиться, что QAction не плодятся в памяти при каждом создании меню
« Последнее редактирование: Апрель 05, 2010, 10:45 от Гурман » Записан

2^7-1 == 127, задумайтесь...
whirlwind
Гость
« Ответ #7 : Апрель 05, 2010, 11:18 »

но в то же время, я при создании каждого QAction осознанно передаю указатель на QMenu, как на родителя - соответственно, при удалении родительского виджета должны удалиться все его дети

Сорри, конечно, в таком случае они удалятся. Просто я назначаю родителем actions всю форму, а не меню.

Еще один момент -- в вашей архитектуре прийдется извращаться, чтобы реализовать хоткеи. А если бы actions хранились где-то отдельно, оно бы само собой получалось.
Записан
Makss
Гость
« Ответ #8 : Апрель 05, 2010, 11:22 »

Цитировать
Еще один момент -- в вашей архитектуре прийдется извращаться, чтобы реализовать хоткеи. А если бы actions хранились где-то отдельно, оно бы само собой получалось.

Во как раз в тему))
У меня недавно была проблема именно с этим моментом, создаю меню, акшины, ставлю хоткеи, но они блин не хотят работать)))))
Как именно и где создавать меню и экшины чтобы хоткеи срабатывали?

Если главное меню программы - ну эт то которое сверху окна, там у меня всегда всё нормально было, а вот в сплывающем меню так и не разобрался(
Записан
crossly
Гость
« Ответ #9 : Апрель 05, 2010, 12:50 »

ответ чуть выше.... если родитель экшина форма то хоткеи должны работать нормально.... если меню.... то и работать они не будут до создания меню...
Записан
Makss
Гость
« Ответ #10 : Апрель 05, 2010, 13:48 »

спс попробуем)
Записан
Гурман
Гуру общения
******
Offline Offline

Сообщений: 1442

Qt 2.2, 3.3, 4.5, 4,7, 4.8, 5.3, 5.6, 5.9, 5.12


Просмотр профиля
« Ответ #11 : Апрель 05, 2010, 15:05 »

Еще один момент -- в вашей архитектуре прийдется извращаться, чтобы реализовать хоткеи. А если бы actions хранились где-то отдельно, оно бы само собой получалось.

ну не знаю, если определение хоткеев в топ-меню, которое над формой - это извращение... хоткеи у меня там определены, и на ура работают, правда там получились дубли акций, но я их уже не руками создаю, они автоматом генерятся из mainwindow.ui
Записан

2^7-1 == 127, задумайтесь...
Makss
Гость
« Ответ #12 : Апрель 05, 2010, 15:08 »

задавать родителя у экшенов форму - не помогло)

помогло если я эти же самые экшины в форму добавляю - addAction(), именно те же самые что и для меню - новые не создаю!!!
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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