鼠标事件由于QGL视图而被阻止 [英] Mouse events blocked because of QGL View

查看:106
本文介绍了鼠标事件由于QGL视图而被阻止的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了一个简单的项目来显示我在更大的应用程序中遇到的问题.
因此,我创建了一个带有2个按钮的主窗口.我创建了一个从QWidget继承并带有2个按钮和QGL视图的类.
问题是,显然由于某种原因(我找不到),此QGL视图的创建阻止了视图的某些事件,尤其是鼠标事件.在下面的代码中,未检测到按钮和类1的主窗口小部件上的鼠标悬停事件(光标必须分别从箭头"变为手"并等待),而鼠标光标在主窗口"按钮上的变化很好(但在实际应用中,它比简单的悬停事件还要严重.)
我精确地说,此问题仅出现在Mac 10.6和更高版本上,而不出现在Windows上.我使用的是Qt 5.1.

I created a simple project to show the problem I have in a bigger application.
So, I create a mainwindow with 2 buttons. I create a class which inherit from QWidget with 2 buttons and a QGL view.
The problem is that, apparently and for some reason I don't find, the creation of this QGL view blocks some events of the views, particularly mouse events. In the code below, the mouse hover events on the buttons and the main widget of class 1 are not detected (the cursor has to change from Arrow to hand and wait respectively) whereas the mouse cursor changes well on the mainwindow buttons (but in my real application, it's more serious than a simple hover event).
I precise that this problem appears only on Mac 10.6 and superior, and not on Windows. I use Qt 5.1.

这是代码:

mainwindow.h:

mainwindow.h :

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

class Class1;
class PanoramaGLView;

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private:
    Ui::MainWindow *ui;
    Class1 *c1;
    PanoramaGLView *gl;
};

#endif // MAINWINDOW_H

mainwindoww.cpp:

mainwindoww.cpp :

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <iostream>
using namespace std;

#include "class1.h"
#include "panoramaglview.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    c1=new Class1(0);
    ui->centralLayout->addWidget(c1);

    //if created here, no problem with mouse cursor on mainwindow buttons but not what I want
    //gl=new PanoramaGLView(0);
    //ui->centralLayout->addWidget(gl);
}

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

myglview.h:

myglview.h :

#ifndef MYGLVIEW_H
#define MYGLVIEW_H

#include <QGraphicsView>
#include <QtOpenGL/QGLWidget>

class MyGLView : public QGraphicsView
{
    Q_OBJECT

public:
    MyGLView(QWidget* pParent = 0);
    virtual ~MyGLView();

protected:
    QGLWidget* m_pGLWidget;
};

#endif // MYGLVIEW_H

myglview.cpp:

myglview.cpp :

#include "myglview.h"

MyGLView::MyGLView(QWidget* pParent)
: QGraphicsView(pParent)
{
    m_pGLWidget = new QGLWidget(QGLFormat(QGL::SampleBuffers | QGL::AlphaChannel));
    m_pGLWidget->makeCurrent();
    setViewport(m_pGLWidget);

    setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
    setViewportUpdateMode(QGraphicsView::FullViewportUpdate);
}

MyGLView::~MyGLView()
{
    delete m_pGLWidget;
}

class1.h:

#ifndef CLASS1_H
#define CLASS1_H

#include <QWidget>

class MyGLView;

namespace Ui {
class Class1;
}

class Class1 : public QWidget
{
    Q_OBJECT

public:
    explicit Class1(QWidget *parent = 0);
    ~Class1();

private:
    Ui::Class1 *ui;

public slots:
    void click1();
};

#endif // CLASS1_H

class1.cpp:

class1.cpp :

#include "class1.h"
#include "ui_class1.h"

#include "myglview.h"
#include <iostream>
using namespace std;

Class1::Class1(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Class1)
{
    ui->setupUi(this);

    MyGLView *glv=new MyGLView(0);
    ui->verticalLayout->addWidget(glv);

    connect(ui->pushButton,SIGNAL(clicked()),this,SLOT(click1()));
}

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

void Class1::click1(){
    cout<<"Class1::click1()"<<endl;
}

mainwindow.ui:

mainwindow.ui :

    <?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>MainWindow</class>
 <widget class="QMainWindow" name="MainWindow">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>400</width>
    <height>300</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>MainWindow</string>
  </property>
  <widget class="QWidget" name="centralWidget">
   <layout class="QVBoxLayout" name="centralLayout">
    <item>
     <widget class="QWidget" name="widget" native="true">
      <property name="styleSheet">
       <string notr="true">background-color: rgb(255, 54, 76);</string>
      </property>
      <layout class="QHBoxLayout" name="horizontalLayout">
       <item>
        <widget class="QPushButton" name="pushButton">
         <property name="cursor">
          <cursorShape>PointingHandCursor</cursorShape>
         </property>
         <property name="text">
          <string>PushButton</string>
         </property>
        </widget>
       </item>
      </layout>
     </widget>
    </item>
   </layout>
  </widget>
 </widget>
 <layoutdefault spacing="6" margin="11"/>
 <resources/>
 <connections/>
</ui>

class1.ui:

class1.ui :

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>Class1</class>
 <widget class="QWidget" name="Class1">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>400</width>
    <height>300</height>
   </rect>
  </property>
  <property name="cursor">
   <cursorShape>WaitCursor</cursorShape>
  </property>
  <property name="windowTitle">
   <string>Form</string>
  </property>
  <property name="styleSheet">
   <string notr="true"/>
  </property>
  <layout class="QVBoxLayout" name="verticalLayout">
   <item>
    <widget class="QPushButton" name="pushButton">
     <property name="cursor">
      <cursorShape>PointingHandCursor</cursorShape>
     </property>
     <property name="text">
      <string>1</string>
     </property>
    </widget>
   </item>
   <item>
    <widget class="QPushButton" name="pushButton_2">
     <property name="cursor">
      <cursorShape>PointingHandCursor</cursorShape>
     </property>
     <property name="text">
      <string>2</string>
     </property>
    </widget>
   </item>
  </layout>
 </widget>
 <resources/>
 <connections/>
</ui>

如果我不创建GL视图,那么当然没有问题.如果我直接在MainWindow中创建myGLView实例,而不使用class1,它也可以工作.但是我需要创建不同的视图,而不是全部在mainwindow中创建(通常是ui的创建方式).
我认为,由于事件是从父级传递到子级的,因此我创建视图,视图的父级或类似对象的方式存在问题,因此我认为问题与此相关.如果运行良好,则当鼠标经过按钮1和2(手形光标)并且仅将class1主窗口小部件(等待光标)悬停时,鼠标光标必须更改.

有什么想法吗?

If I don't create the GL view, there is no problem of course. And if I create the myGLView instance directly in MainWindow, without class1, it works too. But I need to create différents views and not all in mainwindow (which is usually how ui are created).
In my opinion, it's a problem with the way I create the view, its parent or something like that, as event are passed from parent to child, so I think the problem has a link with that. If it works well, the mouse cursor has to change when the mouse passes over the buttons 1 and 2 (hand cursor) and just hover class1 main widget (waiting cursor).

Any ideas?

推荐答案

我可以确认这是回归.在OS X 10.8.4上测试.它在Qt 4.8.5下工作,在Qt 5.1.0下不工作.您应该将其报告为错误.下面是一个合理的单文件测试用例,您下次将其发布到stackoverflow时将知道该测试用例:)

I can confirm that this is a regression. Tested on OS X 10.8.4. It works under Qt 4.8.5, doesn't work under Qt 5.1.0. You should report it as a bug. Below is a sane single-file test case that you will know to produce the next time you post to stackoverflow :)

//main.cpp
#include <QApplication>
#include <QPushButton>
#include <QStackedWidget>
#include <QVBoxLayout>
#include <QGraphicsView>
#include <QGLWidget>

class TestView : public QGraphicsView
{
public:
    explicit TestView(QWidget* parent = 0) : QGraphicsView(parent) {
        setViewport(new QGLWidget());
        setScene(new QGraphicsScene(this));
        scene()->addEllipse(-50, -50, 100, 100, QPen(Qt::red), QBrush(Qt::lightGray));
    }
};

class Pane : public QWidget
{
public:
    explicit Pane(bool hasView, const QCursor & cur, QWidget *parent = 0) :
        QWidget(parent)
    {
        QVBoxLayout * l = new QVBoxLayout(this);
        QPushButton * btn = new QPushButton("[Pane]");
        btn->setCursor(cur);
        l->addWidget(btn);
        if (hasView) l->addWidget(new TestView()); else l->addStretch();
    }
};

class MainWindow : public QWidget
{
    Q_OBJECT
    QStackedWidget *sw;
public:
    explicit MainWindow(QWidget *parent = 0) : QWidget(parent) {
        QVBoxLayout *l = new QVBoxLayout(this);
        QPushButton *btn = new QPushButton("[Main Window] Flip Pages");
        btn->setCursor(Qt::PointingHandCursor);
        connect(btn, SIGNAL(clicked()), SLOT(nextPage()));
        sw = new QStackedWidget();
        l->addWidget(btn);
        l->addWidget(sw);
        sw->addWidget(new Pane(true, Qt::OpenHandCursor));
        sw->addWidget(new Pane(false, Qt::ClosedHandCursor));
    }
    Q_SLOT void nextPage() { sw->setCurrentIndex((sw->currentIndex() + 1) % sw->count()); }
};

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    return a.exec();
}

#include "main.moc"

这篇关于鼠标事件由于QGL视图而被阻止的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆