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

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

Страниц: [1] 2 3 ... 7   Вниз
  Печать  
Автор Тема: Контекстное меню и QAction  (Прочитано 37390 раз)
Spark
Гость
« : Июнь 13, 2013, 12:48 »

Доброго времени суток всем!
Вот такой вопрос новичка.
Поставил на тулбар кнопку и определил действие для нее (вернее сказать, так устроена программа, которую я выбрал для экзекуции, потихоньку обучаясь):
Код:
  enBat = Toolbar->addAction( QIcon( ":/icons/enbat.png" ), tr( "En Bat" ) );

  Toolbar->widgetForAction( enBat )->setObjectName( "enButton" );

  connect( enBat, SIGNAL( toggled( bool ) ),
           this, SLOT( enToggled( bool ) ) );
        
Теперь необходимо задать контекстное меню для этой кнопки. И решить это в лоб не получилось:
Код:
  enBat->setContextMenuPolicy( Qt::CustomContextMenu );   
 
  connect( enBat, SIGNAL( customContextMenuRequested( const QPoint & ) ),
           this, SLOT( context( const QPoint & ) ) );

Ну и понятно дело не получилось. А как надо?
Т.е. примерно понимаю, что  надо добавить виджет а в него уже вставить это действие. Ставил кнопку на тулбар. Прописал:
Код:
  scButton = new QToolButton( Toolbar );
  scButton->setIcon( QIcon (":/icons/enbat.png") );
  scButton->setPopupMode( QToolButton::InstantPopup );
  scButton->addAction( enBat );
  scButton->setContextMenuPolicy( Qt::CustomContextMenu );

  Toolbar->addWidget(scButton);

  connect( scButton, SIGNAL( customContextMenuRequested( const QPoint & ) ),
           this, SLOT( context( const QPoint & ) ) );
Но эффект несколько иной. У этой кнопки появляется ниспадающее меню в котором можно нажать на кнопку.
А в оригинале enBat дает кнопку с триггерным эффектом вкл./выкл. Нужно точно такая же, но + контекстное меню.

В общем как быть?
« Последнее редактирование: Июнь 15, 2013, 15:56 от Spark » Записан
VPS
Гость
« Ответ #1 : Июнь 13, 2013, 13:27 »

попробуйте вместо:
Код:
scButton->setPopupMode( QToolButton::InstantPopup );
использовать другой режим, например "QToolButton::MenuButtonPopup", и выставьте для кнопки "setCheckable(true)"...
Записан
Spark
Гость
« Ответ #2 : Июнь 13, 2013, 14:13 »

попробуйте вместо:
Код:
scButton->setPopupMode( QToolButton::InstantPopup );
использовать другой режим, например "QToolButton::MenuButtonPopup", и выставьте для кнопки "setCheckable(true)"...
Спасибо! Сработало. Поскольку нет необходимости  меню по левой кнопке, то использовал "QToolButton::DelayedPopup". Однако есть проблемка. Маленький треугольничек в уголке кнопки все равно присутствует. И иногда как то срабатывает выпадающее меню по левому клику мыши (не контекстное, а кнопка QAction enBat). Как от этого избавится?
Записан
VPS
Гость
« Ответ #3 : Июнь 13, 2013, 15:14 »

Чтобы не было треугольника внизу, не надо добавлять объект типа "QMenu" в методе "setMenu" кнопки...
Но тогда Вам надо будет самому реализовать обображение контекстного меню...

Поскриптум: Вам, наверное легче будет отнаследоваться от QToolButton и создать свою кнопку с контекстным меню (если его содержимое не меняется) или создать фильтр на событие "QEvent::ContextMenu", и присоединить его к объекту типа QToolButton...
« Последнее редактирование: Июнь 13, 2013, 15:35 от vps » Записан
Spark
Гость
« Ответ #4 : Июнь 13, 2013, 15:51 »

Спасибо за советы. Без них я бы еще долго разбирался.
В конечном итоге фактически переназначил все на новую кнопку. Работает.
Осталось только от самого QAction избавиться, за ненадобностью. Но если просто удаляю, то перестает все работать. Ладно, надеюсь самостоятельно разобраться на чем и где все завязано.
Записан
VPS
Гость
« Ответ #5 : Июнь 13, 2013, 16:04 »

Во вложении пример того, что выше написал...
Записан
Spark
Гость
« Ответ #6 : Июнь 13, 2013, 17:33 »

Спасибо почти все сделал. Но не дает покоя QAction enBat. Пока лишняя кнопка на тулбаре.
На нее завязано меню в трее:
Код:
trayIconMenu.addAction( enBat );
Можно ли как то по простому переназначить на scButton.
Извините если вопросы слишком просты. Но уже столько каши в голове после поисков ответов и метода проб и ошибок.
Записан
VPS
Гость
« Ответ #7 : Июнь 13, 2013, 17:59 »

Вместо того, чтобы в QToolBar сразу добавлять действие, можно сначала отдельно создать объект типа QAction, затем создать объект типа QToolButton, потом связать объект-действие с кнопкой (при помощи метода void QToolButton::setDefaultAction ( QAction * action ) [slot]) и меню в трее. А уже в QToolbar добавлять кнопку. Тогда у Вас не будет дублирования...

Поскриптум: сам не пробовал, но, по моему, должно работать...
Записан
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4732



Просмотр профиля WWW
« Ответ #8 : Июнь 13, 2013, 18:05 »

enBat технически не является кнопкой если что, это QAction. эту «кнопку» из тулбара всегда можно убрать — экшн от этого не перестанет работать.

в меню можно добавлять только QAction'ы, кнопки нельзя.
Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
Spark
Гость
« Ответ #9 : Июнь 13, 2013, 18:35 »

enBat технически не является кнопкой если что, это QAction. эту «кнопку» из тулбара всегда можно убрать — экшн от этого не перестанет работать.

в меню можно добавлять только QAction'ы, кнопки нельзя.
Понимаю. Я для ясности описал, что мне мешает на тулбаре. Просто QAction на чем то завязан. И если я его просто убираю, то конечно кнопки не будет. Но и программа перестает работать. Если убрать иконку. То надпись остается. Если и ее убрать, то не компилируется. Ну в общем, что то недопонимаю.
С этим потом разберусь. Этот QAction удалил. В общем то на меню в трее было завязано и там пытаюсь связать меню уже с новой кнопкой.
И здесь конечно опять в лоб не получается:
Код:
  connect( trayIconMenu.addAction( QIcon( ":/icons/enbat.png" ), tr( "En Bat" ) ), SIGNAL( triggered( bool )),
           this, SLOT( enToggled( bool ) ) );
Лишней кнопки уже нет конечно, но и новая кнопка в трее ни с чем не связана (не рабочая).
Записан
Spark
Гость
« Ответ #10 : Июнь 13, 2013, 18:43 »

Вместо того, чтобы в QToolBar сразу добавлять действие, можно сначала отдельно создать объект типа QAction, затем создать объект типа QToolButton, потом связать объект-действие с кнопкой (при помощи метода void QToolButton::setDefaultAction ( QAction * action ) [slot]) и меню в трее. А уже в QToolbar добавлять кнопку. Тогда у Вас не будет дублирования...

Поскриптум: сам не пробовал, но, по моему, должно работать...
Спасибо. Будем пробовать. Уже почти все получилось. Вернее первоначальная задача выполнена. Сама по себе новая кнопка на тулбаре работает  и контекстное меню зацепил. Осталось связать новую кнопку везде где она фигурирует (вернее фигурирует прежний QAction) - В настройках и в трее. Хотя бы с треем связать. Но мозги кипят уже порядком Улыбающийся.
А вообще спасибо за реальную помощь. Вчера день потратил на то как вообще сделать контекстное меню для виджета. С этим справился. Читая форум и рыская по справке, все равно с малым опытом все вокруг да около переправлять чужие исходники.
Сегодня день потратил как QAction переделать для этой цели, прежде чем спросил совета. И небольшая подсказка как раз направила в нужное русло.
« Последнее редактирование: Июнь 13, 2013, 18:52 от Spark » Записан
VPS
Гость
« Ответ #11 : Июнь 13, 2013, 18:47 »

Вместо того, чтобы в QToolBar сразу добавлять действие, можно сначала отдельно создать объект типа QAction, затем создать объект типа QToolButton, потом связать объект-действие с кнопкой (при помощи метода void QToolButton::setDefaultAction ( QAction * action ) [slot]) и меню в трее. А уже в QToolbar добавлять кнопку. Тогда у Вас не будет дублирования...

Поскриптум: сам не пробовал, но, по моему, должно работать...

Во вложении пример выше описанного...
Записан
Spark
Гость
« Ответ #12 : Июнь 13, 2013, 19:47 »

Во вложении пример выше описанного...
Код:
Спасибо. Попробовал. Код для кнопки похудел:
  scButton = new QToolButton( navToolbar );
  scButton ->setDefaultAction( enBat );
  scButton ->setContextMenuPolicy( Qt::CustomContextMenu );
  Toolbar->addWidget( scButton );

  connect( scButton, SIGNAL( customContextMenuRequested( const QPoint & ) ),
           this, SLOT( context( const QPoint & ) ) );
Теперь связи все сохранились и в рабочем состоянии, поскольку все завязано на enBat.

Но на тулбаре две кнопки Улыбающийся. Будем разбираться.

P.S. Все таки в данном случае это не тот путь. Слишком много дополнительных связей получается. Переделать которые сложнее. Убираем иконку QAction - рушаться все связи.

С нуля такой вариант был бы не плох. А так не ясно, можно ли вообще убрать в этом случае иконку QAction безнаказанно с тулбара.
« Последнее редактирование: Июнь 13, 2013, 20:37 от Spark » Записан
VPS
Гость
« Ответ #13 : Июнь 13, 2013, 20:54 »

Или я чего-то не понимаю.....
Но всё-же, вместо вот этого куска кода:
Код:
enBat = Toolbar->addAction( QIcon( ":/icons/enbat.png" ), tr( "En Bat" ) );
Toolbar->widgetForAction( enBat )->setObjectName( "enButton" );
 connect( enBat, SIGNAL( toggled( bool ) ), this, SLOT( enToggled( bool ) ) );

Сделайте что-то типа:
Код:
QAction *enBat = new QAction(QIcon( ":/icons/enbat.png" ), tr( "En Bat" ));
QToolButton *scButton = new QToolButton( navToolbar );
scButton->setDefaultAction( enBat );
scButton->setContextMenuPolicy( Qt::CustomContextMenu );
Toolbar->addWidget( scButton );
и т.д.
Тогда у вас будет указатель на enBat, с которым Вы можете делать всё, что угодно...
И если делать, как в примере, то не будет второй кнопки с такой же функциональностью...
« Последнее редактирование: Июнь 13, 2013, 20:59 от vps » Записан
Spark
Гость
« Ответ #14 : Июнь 14, 2013, 05:19 »

Так вроде я примерно так и делаю. Хотя для меня может быть какая то разница не очевидна (не болmше месяца как вообще с C++ и Qt) которая имеет значение.
Там и без кнопки проблем хватает, но хотя бы с ней разобраться. Почему у меня их две на тулбаре?
Вот упростил свой код, который в листинге:
Код:
  enBat = Toolbar->addAction( QIcon( ":/icons/enbat.png" ), tr( "En Bat" ) );

  scButton = new QToolButton( Toolbar );
  scButton->setDefaultAction( enBat );
  Toolbar->addWidget( scButton );
Разве это не то же самое, что в ваших примерах?
Тулбар, Экшин и Кнопка декларированы в другом файле.
После этого на тулбаре появляется дублирующая кнопка (судя по логике так и должно было произойти).
Для трея это нормальная ситуация. Если Экшен и кнопка на одном тулбаре, то у меня пока не получается задуманный результат. Криво можно сделать - второй тулбар Улыбающийся. Но некрасиво.
Но возможно я не понимаю разницу между вашим примером и тем, что сделал я.

Вообще возможно публиковать Экшен без определения его в интерфейс? Пока писал эту строку до меня дошла разница между вашим и моим кодом Улыбающийся. Буду править.
Записан
Страниц: [1] 2 3 ... 7   Вверх
  Печать  
 
Перейти в:  


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