由于QGL View,鼠标事件被阻止

时间:2013-08-26 12:44:12

标签: qt mouseevent qglwidget

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

以下是代码:

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:

#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:

#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:

#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:

#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:

    <?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:

<?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,它也可以。但我需要创建différents视图而不是所有在mainwindow中(通常是如何创建ui) 在我看来,这是我创建视图,它的父或类似的东西的方式的问题,因为事件从父传递到子,所以我认为问题有一个链接。如果它运行良好,当鼠标经过按钮1和2(手形光标)并且只悬停class1主窗口小部件(等待光标)时,鼠标光标必须改变。

有什么想法吗?

1 个答案:

答案 0 :(得分:0)

我可以确认这是一个回归。在OS X 10.8.4上测试过。它在Qt 4.8.5下工作,在Qt 5.1.0下不起作用。您应该将其报告为错误。下面是一个理智的单文件测试用例,您将知道在下次发布到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"