Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > С/С++: Кроссплатформенное программирование, Qt/Gtk+/wxWidgets > Перемещение мыши


Автор: kuvshinka 23.1.2014, 14:45
На главной форме приложения при определенной X-координате мыши появляется всплывающее меню QMenu, после чего при движении мыши не срабатывает метод mouseMoveEvent(QMouseEvent *event) главной формы, наверное из-за передачи фокуса в появившееся меню...как мне сделать так, чтобы при движении мыши по главной форме ВСЕГДА срабатывал бы ее метод mouseMoveEvent?

Делаю так
Код

Mainclass::Mainclass()
{
 this->setMouseTracking(true);
 myMenu = new QMenu(this);
 myMenu->setFocusPolicy(Qt::NoFocus); // не помогает
}
////-----------------------------------------------------------------------------------
void Mainclass::mouseMoveEvent(QMouseEvent *event)
{
 if (event->pos().x()>100)
   myMenu->show();
 else
  myMenu->hide();
}
////-----------------------------------------------------------------------------------

Автор: vinter 23.1.2014, 15:14
поставь фильтр(installEventFilter) на сообщения QMenu, и верни для MouseMove false.

Автор: kuvshinka 23.1.2014, 21:05
vinter: а можно примерчик, а то я что-то не поняла что к чему надо сделать...

Автор: vinter 24.1.2014, 09:46
посмотри документацию к installEventFilter, там есть пример

Автор: kuvshinka 27.1.2014, 14:43
Пробую так
Код


Mainclass::Mainclass()
{
 this->setMouseTracking(true);
 myMenu = new QMenu(this);
 myMenu->setFocusPolicy(Qt::NoFocus); // не помогает
 myMenu ->installEventFilter(this);
}

bool Mainclass::eventFilter(QObject *obj, QEvent *ev)
{
    if (ev->type() == QEvent::MouseMove)
    {
     qDebug() << "filter...";
     return true;
   }
}

вообще не вызывается eventFilter при отображении myMenu  и что значит «верни для MouseMove false»? Подскажите пож-та что неверно в моем примере и как это исправить...

Автор: vinter 27.1.2014, 15:59
Попробуй так:
Код

Mainclass::Mainclass()
{
 this->setMouseTracking(true);
 myMenu = new QMenu(this);
 myMenu->setMouseTracking(true);
 myMenu ->installEventFilter(this);
}

bool Mainclass::eventFilter(QObject *obj, QEvent *ev)
{
    if (ev->type() == QEvent::MouseMove)
    {
     qDebug() << "filter...";
     return false;
   }
   return true;
}

Автор: kuvshinka 28.1.2014, 09:38
vinter, К указанному Вами выше примеру добавляю
Код

void Mainclass::mouseMoveEvent(QMouseEvent *event)
{
    qDebug() << "mouse pos:  " << event->pos().x();

    if (event->pos().x()>=100)
     myMenu->show();   
    // else
    // myMenu->hide();
}

в итоге после появления всплывающего меню ПРОГРАММА и КОМПЬЮТЕР ЗАВИСАЮТ...

Автор: vinter 28.1.2014, 11:17
kuvshinka, я тебе показал, как пропустить события MoseMove из меню в изначальную форму. Как справляться с остальным? Думай сама, для меня эта ситуация выглядит глупой т.к. меню, не должно отдавать мышь форме. Видимо у тебя какая-то логика с этим связана, а значит решай как тебе поступать. 
"Висит" у тебя, скорее всего из-за перекрестных событий, которые попадают в цикл зависимости друг от друга.
В качестве варианта, можно попробовать выставлять флаг, когда меню показано и не выполнять if (event->pos().x()>=100) в этом случае. В общем надо смотреть с дебагером и разбираться.

Добавлено через 55 секунд
P.S. Компьютер не должен зависать из-за одной программы.

Автор: ALEXRAGE 28.1.2014, 12:14
Думаю просто нужно передать QMouseEvent *event дальше на обработку.
Что-то типа QMenu::mouseMoveEvent(event);


Автор: kuvshinka 29.1.2014, 15:39
vinter:
Да нет там никакой особой логики – в новый проект вставила ваш пример + мой обработчик mouseMoveEvent (см. Test.rar) и получается такое зависание (а компьютер зависает, если программу запустить под убунтой, под виндой программа тоже виснет, но ее можно хотя бы остановить).

Автор: vinter 29.1.2014, 18:11
kuvshinka, логика у тебя уже есть. Ты пытаешься прокидывать сообщения из контекстного меню на форму. Но в обработчике этих сообщений ты манипулируешь меню. Не видишь рекурсии? Ты должна разобраться с этим, это твоя логика. Она должна исключить рекурсию. 

С помощью отладчика тоже можно довольно быстро отыскать проблему.

Автор: kuvshinka 29.1.2014, 21:53
да даже если я перенесу код отображения диалога, допустим, в онклик кнопки и соответственно оставлю Mainclass::mouseMoveEvent пустым и даже если и Mainclass::eventFilter(QObject *obj, QEvent *ev) сделаю пустым, то все равно меню будет появляться без его пунктов и программа подвиснет...

Автор: ALEXRAGE 30.1.2014, 16:06
Немного доработал Test.
Вроде удалось проблему решить. 

Автор: kuvshinka 31.1.2014, 22:00
ALEXRAGE: уже лучше, программа на зависает, спасибо за пример, но мне надо немного другое - чтобы диалог появлялся при, допустим Xmouse main-формы<=100 и, если указатель мыши находится на диалоге, то диалог виден, при выходе курсора за пределы диалога последний должен исчезать...

Автор: ALEXRAGE 3.2.2014, 09:04
Цитата(kuvshinka @ 31.1.2014,  22:00)
если указатель мыши находится на диалоге, то диалог виден, при выходе курсора за пределы диалога последний должен исчезать...

Ну тогда нужно создать свой класс-обертку "меню". Относледовать его от QMenu и переопределить методы enterEvent и leaveEvent. Ну и в leaveEvent соответственно прописать this->hide().  

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)