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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: [РЕШЕНО почти] grabMouse in QDialog  (Прочитано 6464 раз)
vintik
Гость
« : Июнь 04, 2013, 18:03 »

Всем привет, столкнулся с проблемой, самостоятельно решить не могу.

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

Делаю примерно так (хотя пробовал по-всякому - но работать заставить не удалось)

Код:
void MainWindow::on_menuModal_dialog_triggered(QAction *action)
{
    modal_dialog_wrapper dialog;
    dialog.exec();
}

где:

Код:
int modal_dialog_wrapper::exec()
{
    show(); // это из-за того что в хелпе написано Note: Only visible widgets can grab mouse input. If isVisible() returns false for a widget, that widget cannot call grabMouse().
    grabMouse();
    int ret = QDialog::exec();
    releaseMouse();
    return ret;
}

Не работает и всё тут.
Попробовал написать совсем простой пример

Код:
#include <QApplication>
#include <QWidget>
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QWidget w;
    w.show();
    w.grabMouse();
    // w.grabMouse();
    // w.grabMouse();
    // w.grabMouse();
    // w.grabMouse();
    // w.grabMouse();
    return a.exec();
}

Не работает. Однако если раскомментить повторные вызовы w.grabMouse(); - работает.

Юзаю Qt-4.8.3. Ось kubuntu 12.10
« Последнее редактирование: Июнь 27, 2013, 19:21 от vintik » Записан
gil9red
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 1805



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

Код:
#include <QApplication>
#include <QWidget>
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QWidget w;
    w.exec();
    return a.exec();
}
Записан

vintik
Гость
« Ответ #2 : Июнь 04, 2013, 18:26 »

Код:
#include <QApplication>
#include <QWidget>
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QWidget w;
    w.exec();
    return a.exec();
}

Не понял ответа - тут просто будет создан виджет и всё. Никаким захватом мыши и не пахнет.
Ведь смысл перехватывать ВСЕ нажатия, даже мимо виджета.
Записан
gil9red
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 1805



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

Тьфу, не обратил внимание
замените QWidget на QDialog
и вызовите у него метод exec()

Код:
QDialog w;
w.exec();

окно станет модальным
Записан

vintik
Гость
« Ответ #4 : Июнь 04, 2013, 18:39 »

Ок, усложняем задачу. Такой код
Код:
#include <QApplication>
#include "widget.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();

    return a.exec();
}

Код:
#ifndef WIDGET_H
#define WIDGET_H

#include <QtGui>

namespace Ui {
class Widget;
}

class Widget : public QDialog
{
    Q_OBJECT
   
public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();

private:
    void mousePressEvent(QMouseEvent *event);
    void wheelEvent(QWheelEvent *event);
private:
    Ui::Widget *ui;
};

#endif // WIDGET_H

Код:
#include "widget.h"
#include "ui_widget.h"
#include <QDebug>

Widget::Widget(QWidget *parent)
    : QDialog(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    ui->frame->show();
    ui->frame->grabMouse();
}

Widget::~Widget()
{
    delete ui;
}

void Widget::mousePressEvent(QMouseEvent *event)
{
    qDebug() << "mousePressEvent";
}

void Widget::wheelEvent(QWheelEvent *event)
{
    qDebug() << "wheelEvent";
}


ui файл - просто виджет, внутри которого установлен QFrame (ui->frame)
Под kubuntu 12.10 мышь не будет захвачена
Записан
gil9red
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 1805



Просмотр профиля WWW
« Ответ #5 : Июнь 04, 2013, 19:16 »

Уберите этот код
Код:
    ui->frame->show();
    ui->frame->grabMouse();


main.cpp:
Код:
#include <QApplication>
#include "widget.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.exec();

    return a.exec();
}


Или я вообще ничего не могу понять Улыбающийся
Записан

vintik
Гость
« Ответ #6 : Июнь 04, 2013, 19:31 »

мне необходимо, чтобы после отображения на экране диалога любые события мыши были перехвачены.
Даже если делается клик мимо диалога или колесо вращается не над ним мне нужно отловить это событие в этом диалоге.
Согласно докам для этого служит метод grabMouse, но вот как его заставить правильно работать - я не понимаю
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #7 : Июнь 04, 2013, 20:36 »

QWidget::show() асинхронный вызов, т.е. наличие окна после него не является обязательным.
Перегрузи QWidget::showEvent() и уже в нём делай граб.
Записан

Qt 5.11/4.8.7 (X11/Win)
vintik
Гость
« Ответ #8 : Июнь 05, 2013, 00:43 »

QWidget::show() асинхронный вызов, т.е. наличие окна после него не является обязательным.
Перегрузи QWidget::showEvent() и уже в нём делай граб.

Это интересно, спасибо, не знал

попробовал сделать так, но не заработало

Код:
void Widget::showEvent(QShowEvent *event)
{
    ui->frame->grabMouse();
}

Вообще, в доке написано, что это событие (showEvent) - если оно non spontaneous - приходит до появления окна (а оно именно non spontaneous).
А как бы получить уведомление от оконной системы, что окно уже реально видимо?
Кстати, попробовал сделать grabMouse() с задержкой

Код:
QTimer::singleShot(100, this, SLOT(timeout_slot())); // в timeout_slot() делаю ui->frame->grabMouse()

и так вот работает. Так что мы на верном пути, осталось понять как его "завершить"
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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