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

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

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: QTreeWidget, сигнал itemClicked и кнопки мышки  (Прочитано 19586 раз)
CoderInside
Гость
« : Март 03, 2006, 21:08 »

Добрый день!
Есть QTreeWidget (полный QTreeWidgetItem'ов Подмигивающий). Программа должна работать так: когда пользователь нажимает на этом дереве левой кнопкой мыши - строка должна подсвечиваться, а когда правой кнопкой - должно появляться контекстное меню...
Показ меню привязываем к сигналу itemClicked QTreeWidget'а, но этот сигнал возникает всегда, неважно т.е. на какую кнопку нажали. Сколько не бились сделать так, чтобы меню появлялось по правой кнопке мыши - так ничего и не получилось  :? Оно появляется всегда!
Подскажите как поступить в этом случае... Как сделать так, чтобы контекстное меню вызывалось по правому клику мышки?
Заранее большое спасибо!
Qt 4.1.1 (VS2003)
Записан
Joe
Гость
« Ответ #1 : Март 03, 2006, 22:23 »

НЕ НАДО перехватывать itemClicked - надо просто переопределить contextMenuEvent!

void contextMenuEvent(QContextMenuEvent * e);

он как раз для этих целей и написан - чтоб по событию, которое ассоциировано с "требованием" контекстного меню это самое меню предоставить. или НЕ предоставить.

void QTreeWDeriv::contextMenuEvent(QContextMenuEvent * e)
{
// где-то там определились с кучей  actions - чтоб не плодить и коннектить их кажный раз
   if(actions.count() > 0)
   {
      QMenu* menu = new QMenu(this);
      foreach(QAction* action, actions)
      {
         menu->addAction(action);
      }
      menu->exec(e->globalPos());
   }
};
Записан
Вудруф
Гость
« Ответ #2 : Март 04, 2006, 11:51 »

foreach(QAction* action, actions)
{
menu->addAction(action);
}

Э? Разве так можно?!?
*в ауте*
Записан
CoderInside
Гость
« Ответ #3 : Март 04, 2006, 12:26 »

Получилось!
В классе наследованном от QTreeWidget создал сигнал:
Код:
signals:
void itemRMBClicked ( QTreeWidgetItem * item, int column );

Переопределил функцию
Код:
void QWidget::contextMenuEvent ( QContextMenuEvent * event )  [virtual protected]


и в реализации вызываю сигнал

Код:
void SourceTreeWidget::contextMenuEvent (QContextMenuEvent * event)
{
emit itemRMBClicked (currentItem(), currentColumn());
}


Затем соединяю этот сигнал со слотом в которой выполняются требуемые операции и создается PopUp меню:
Код:
connect(mpTWidget,SIGNAL(itemRMBClicked( QTreeWidgetItem*,int)), this,SLOT(OnItemClicked(QTreeWidgetItem*,int)));
Записан
Dendy
Гость
« Ответ #4 : Март 04, 2006, 13:34 »

Хммм... Задача нетривиальная. У меня сходу не получилось её решить. Вопрос к Joe:

А как теперь сделать, чтобьІ по средней кнопке мьІши делалось ещё какое-то собьІтие для item'а, на котором кликнул юзер? А по левой? А по левой с зажатьІм альтом?
Записан
Steven_Orko
Гость
« Ответ #5 : Март 04, 2006, 14:19 »

Цитата: "Dendy"


А как теперь сделать, чтобьІ по средней кнопке мьІши делалось ещё какое-то собьІтие для item'а, на котором кликнул юзер? А по левой? А по левой с зажатьІм альтом?

Я тут посмотрел в Assitant, там про QContextMenuEvent написано следующее:
Цитировать
Context menu events are sent to widgets when a user performs an action associated with opening a context menu. The actions required to open context menus vary between platforms; for example, on Windows, pressing the menu button or clicking the right mouse button will cause this event to be sent.


Т.е. это событие посылается при нажатии правой кнопки мышки. Насколько я знаю в Х11  и Виндах это действие как раз считается вызовом контектсного меню. А вот нажатие правой кнопки мышки совместно с alt, ctrl или shift будет считаться аналогичным действием?
Это я все про Qt 4.1.1, так как ща пользуюсь им.
Записан
Dendy
Гость
« Ответ #6 : Март 04, 2006, 14:28 »

Для етого есть QMouseEvent. Но в случае с QAbstractItemView никакой дополнительной информации как узнать каким образом бьІла нажата кнопка я не нашёл. Може сліпенький... (-:
Записан
Sergey B.
Программист
*****
Offline Offline

Сообщений: 544



Просмотр профиля WWW
« Ответ #7 : Март 04, 2006, 16:33 »

Цитата: "Dendy"
Для етого есть QMouseEvent. Но в случае с QAbstractItemView никакой дополнительной информации как узнать каким образом бьІла нажата кнопка я не нашёл. Може сліпенький... (-:


Где-то на забурном сайте пролетала инфа, около года назад...
Чувак с MFC на Qt проги свои переписывал, такая проблема тоже была... решение ему не сказали  Грустный ... Хотя в MFC это тривиальная задача...
Записан
Dendy
Гость
« Ответ #8 : Март 04, 2006, 17:01 »

Около года назад Qt 4 ещё не бьІло. На Qt 3 для item'ов существует множество перегруженньІх сигналов для получения информации с каким переподвьІподвертом мьІ на него нажали. В Qt 4 етот механизм упростили и теперь сложно найти концьІ. Отсюда и вопросьІ...
Записан
Joe
Гость
« Ответ #9 : Март 06, 2006, 18:20 »

Есть одна загвоздка. не на всех платформах есть мыши с 3мя кнопками (кое где и с 2мя, не дай Бог), поэтому скорее всего Qt решили не заморачивать на "кнопки", а сказали, что будут обслуживать прецеденты. мне кажется, это более правильный подход. А вот как вы сгенерируете это самый прецедент - уже вопрос второй, хотя на самом деле здесь - первый. Определитесь, чего хочется - уметь кнопки от мыши перехватывать, или более полезные вещи делать? Улыбающийся
Конечно, это несколько экзотичное решение, узнавать о назджатии правой кнопки по факту вызова contextMenuEvt, я думаю, всё лежит на поверхности, уж больно рапространённая задача. К тому же, когда есть MouseEvent.

QAbstractItemView - а не слишком ли глубоко зарылись Улыбающийся? Может всё-таки более конкретный класс посмотрите? Часто можно определить, какой item находится под точкой, этого бывайт достаточно для некоторых целей. А если писать свой ItemView (упаси Бог), то такую функциональность бывает полезно самим добавить - и самим же пользовать.
Записан
Steven_Orko
Гость
« Ответ #10 : Март 06, 2006, 23:46 »

to Joe and Dendy
Хотел вот узнать, чем мой пост не подошел? Почему "несколько экзотичное решение, узнавать о назджатии правой кнопки по факту вызова contextMenuEvt"? Если даже в Assistant написано, что эта функция вызывается в случае, когда необходимо показать контекстное меню? В Винде и в Линуксах (точно скажу про Mandriva) нажатие правой кнопки мышки считается вызовом контекстного меню?
Собственно человеку это и надо было, обработать данное событие. Вот и переопределил соответствующую виртуальную член-функцию. ИМХО, в данном вопросе обобщение излишне.
Про mouseEvent. Согласен, что здесь можно отлавливать разные нажатия кнопки мышки и т.д. Но не кажется ли вам, что это стрелять по воробьям из пушки? Зачем повторять тот же код, который уже есть в Qt?
Записан
nEoN
Гость
« Ответ #11 : Март 07, 2006, 12:01 »

2 Steven_Orko
Контекстное меню (contextMenuEvent) может вызываться по разным причинам, не только из за нажатия правой кнопки мыши. Типичный пример соответствующая кнопка на клавиатуре для вызова контекстного меню.
Записан
Dendy
Гость
« Ответ #12 : Март 07, 2006, 13:53 »

В данном случае решение подходит. Но ето как раз та ситуация, когда вьІпрямившись в полньІй рост дотрагиваешься волосами до потолка. Ещё чуть-чуть и прийдётся сгинать шею в поисках черезжопньІх решений. (-:  Извините мой французкий.

Момент принципиальньІй. Ведь поиск как именно бьІла нажата кнопка мьІши можно узнать обратившись к испустившему сигнал обьекту, что нарушает обьектно-ориентированньІй подход, когда испускатель и получатель собьІтия ничего друг о друге не знают. Например, если вьІ захотите ловить нажатие на итем в другом потоке - у вас ничего не получится. Тролли жёстко документируют каждую функцию, которая нарушает етот принцип.

И примеров, где может использоваться реагирование на произвольньІе нажатия мьІши - масса.
Записан
Joe
Гость
« Ответ #13 : Март 07, 2006, 20:36 »

to Steven_Orko
не так сложно взять и переопределить default поведение widget' а для  показа contextmenu. Я посто попытался указать, что задача решается несколько иным образом, это о контесктном меню, а про нажатые клавиши - это вообще из другого места надо смотреть. Но смешивать понятия не всегда полезно, как раз для этого trolltech и сделалито вынесенный event. И многое другое тоже. Вообще, глядя на то, в каком ключе организован этот API - можно многому поучиться - и если следовать этому, весьма простому, правилау - делать то что хочешь в тех местах где это на самом деле надо - можно реализовать весьма сложное поведение с наименьшей головной болью. Они не на 100% придерживаются этой идеологии (точнее - с избытком Улыбающийся) - рассчитывая на разные категории пользователей.
Записан
Dendy
Гость
« Ответ #14 : Март 09, 2006, 10:26 »

КрасивьІе слова. (0:  Но! Почему же тогда Тролли в собственном Ассистанте оставляют такой же ляп:

Когда клацаешь на списке содержимого в Ассистанте левой кнопкой - открьІвается соответствующая страница в текушем окне. Вроде всё верно.

Когда клацаешь правой... (!) Тоже открьІвается страница, заменяя предьІдущую + ОткрьІвается контекстное меню с вариантами "как вьІ хотите открьІть ету страницу".

А теперь попробуйте найти концьІ етого бага и способьІ его исправить. Он тянется из версии в версию. Ощущение, что нет гибкого и красивого способа его исправить, продолжая пользоваться при етом сигналом itemClicked().
Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


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