Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

Форум на CrossPlatform.RU _ Qt GUI _ как инициировать mouseMoveEvent

Автор: mezmay 10.12.2010, 11:19

Мне надо в фукции расположить курсор мыши сначала в точке с координатами (0,0) а потом в точке (width()-1, height()-1). Делаю так:

QMouseEvent me0(QEvent::MouseMove, QPoint(0, 0), Qt::NoButton, Qt::NoButton, Qt::NoModifier);
QWidget::mouseMoveEvent(&me0);
// дальнейште действия

QMouseEvent me1(QEvent::MouseMove, QPoint(width()-1, height()-1), Qt::NoButton, Qt::NoButton, Qt::NoModifier);
QWidget::mouseMoveEvent(&me1);
// дальнейшие действия


второе событие не отрабатывает. Как правильно сделать? может
qApp->processEvents()
вставить? Но куда?

Автор: igor_bogomolov 10.12.2010, 12:06

смотри доки на функции

bool QCoreApplication::sendEvent ( QObject * receiver, QEvent * event ) [static]
void QCoreApplication::postEvent ( QObject * receiver, QEvent * event ) [static]
тебе нужна 1-ая

Автор: mezmay 10.12.2010, 13:04

Результат тот же.
Если поставить qApp->processEvents() после второго sendEvent то отрабатывают два события мыши, но у второго какие-то странные координаты - посередине виджета

Автор: igor_bogomolov 10.12.2010, 13:36

Что то я сразу не догадался, проще будет воспользоваться функцией

void QCursor::setPos ( int x, int y ) [static]
она должна так ка надо отработать

Автор: mezmay 10.12.2010, 13:58

Спасибо, но мне надо чтобы два раза в системе отработало событие перемещения мыши,а после вызова QCursor::setPos оно не отрабатывает (ну или мой виджет их не получает)

Автор: igor_bogomolov 10.12.2010, 14:38

Ну вот смотри - элементарный тестовый пример

Раскрывающийся текст
Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    QPushButton *button = new QPushButton("move cursor",this);
    widget = new QWidget(this);
    widget->setMinimumSize(250,250);

    QVBoxLayout *layout = new QVBoxLayout(this);
    layout->addWidget(widget);;
    layout->addWidget(button);

    widget->installEventFilter(this);
    widget->setMouseTracking(true);

    connect(button, SIGNAL(clicked()), this, SLOT(moveCursor()));
}

bool Widget::eventFilter(QObject *o, QEvent *e)
{
    if (e->type() == QEvent::MouseMove) {
        QMouseEvent *mouse = static_cast<QMouseEvent*>(e);
        qDebug() << mouse << mouse->pos();
    }

    return false;
}

void Widget::moveCursor()
{
    QCursor::setPos (widget->mapToGlobal(QPoint(10,10)));
    QCursor::setPos (widget->mapToGlobal(QPoint(150,150)));
}


Вывод (координаты в шестнадцатиричном виде):
Цитата
QMouseEvent(MouseMove, 0, 0, 0) QPoint(a,a)
QMouseEvent(MouseMove, 0, 0, 0) QPoint(96,96)
Т.е. всё работает так как надо

Автор: mezmay 10.12.2010, 15:46

Я работаю с google maps API в классе, унаследованном от QWebView. То есть у меня отображается html-страница. В тексте этой html-страницы есть код:

google.maps.event.addListener(map, 'mousemove', function(event) {
        var coordinates = event.latLng;
        cMap.onGeo(coordinates.lat(), coordinates.lng());
  });

- это значит что при возникновении события движения мыши из JavaScript вызывается С++ слот моего класса onGeo().

Когда в своем классе я пишу:
QMouseEvent me0(QEvent::MouseMove, QPoint(0, 0), Qt::NoButton, Qt::NoButton, Qt::NoModifier);
    QWebView::mouseMoveEvent(&me0);    

    QMouseEvent me1(QEvent::MouseMove, QPoint(width()-1, height()-1), Qt::NoButton, Qt::NoButton, Qt::NoModifier);
    QWebView::mouseMoveEvent(&me1);

- в этом случае onGeo() вызывается 1 раз (хотя по идее должно 2 раза).
А если написать:
    QCursor::setPos(mapToGlobal(QPoint(0, 0)));

    QCursor::setPos(mapToGlobal(QPoint(width()-1, height()-1)));
- то вообще ни разу... Подскажите как добиться чтобы onGeo вызывалось 2 раза

Автор: SABROG 10.12.2010, 17:23

Мне кажется вы лукавите, если это реальный код, то второй вызов mouseMoveEvent() должен произойти, если приложение не крашится или не зацикливается, иначе это противоречит вообще программной логике.

QMouseEvent me0(QEvent::MouseMove, QPoint(0, 0), Qt::NoButton, Qt::NoButton, Qt::NoModifier);
    QWebView::mouseMoveEvent(&me0);    

    QMouseEvent me1(QEvent::MouseMove, QPoint(width()-1, height()-1), Qt::NoButton, Qt::NoButton, Qt::NoModifier);
    QWebView::mouseMoveEvent(&me1);

Автор: mezmay 14.12.2010, 9:24

Это точно реальный код

Автор: SABROG 14.12.2010, 11:16

Цитата(mezmay @ 14.12.2010, 9:24) *
Это точно реальный код

Тогда объясните мне поведение такого метода:

void foo()
{
    bar();
    bar();
}


Вы говорите, что bar() вызывается только 1 раз. Значит выхода из foo() - не будет! А если его не будет, значит программа будет уже работать некорректно.

Автор: mezmay 14.12.2010, 15:04

mouseMoveEvent вызывается 2 раза как и должно.
Я говорю что onGeo() вызывается 1 раз, и происходит это скорее всего потому что при последовательном выполении операторов на определенное время блокируется принятие событий. (пример - for(int i=0; i<100000; i++){какие-то длительные действия} - программа подвиснет, если это сделать в основном потоке)
Короче надо каким-то образом доставить накопившиеся события (в данном случае событие движения мыши)...

Автор: Rocky 14.12.2010, 15:37

qApp->processEvents()

Автор: SABROG 14.12.2010, 19:00

Цитата(Rocky @ 14.12.2010, 15:37) *
qApp->processEvents()

Зачем человека "уводить" в заведемо неверное направление? :)

Цитата
Короче надо каким-то образом доставить накопившиеся события (в данном случае событие движения мыши)...


Тебе уже сказали как это сделать. Так должно работать:

    QMouseEvent me0(QEvent::MouseMove, QPoint(), 0, 0, 0);
    QMouseEvent me1(QEvent::MouseMove, QPoint(width()-1, height()-1), 0, 0, 0);
    QCoreApplication::sendEvent(this, &me0);
    // do stuff
    QCoreApplication::sendEvent(this, &me1);
    // do stuff


Только убедись, чтобы это было не в конструкторе виджета главного окна и до вызова этих строк был запущен основной цикл событий.

Автор: Rocky 14.12.2010, 22:19

А почему processEvents в данном случае не поможет? Этих событий в главном цикле нет?...А вон оно что, не уделил внимания строке QWebView::mouseMoveEvent(&me0).

Автор: igor_bogomolov 14.12.2010, 23:54

SABROG, без qApp->processEvents() действительно не работает. Причин не выяснял. Может быть есть какая то оптимизация доставляемых событий в контекст JavaScript? Не знаю в общем, могу только догадываться.

mezmay, в приложение рабочий пример для второй версии API карт гугл. В общем там ничего нового, всё то что уже здесь обсудили, но у меня этот код обрабатывает так как задумано. В общем, попробуй

 addressbook.zip ( 8.31 килобайт ) : 76
 

Форум Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)