由于QGL视图,鼠标事件被阻止



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

这是代码:

主窗口.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,它也可以工作。但我需要创建不同的视图,而不是全部在主窗口中(通常是创建ui的方式)
在我看来,这是我创建视图的方式、它的父视图或类似的东西的问题,因为事件是从父视图传递到子视图的,所以我认为问题与此有关。如果效果良好,当鼠标经过按钮1和2(手光标)并仅悬停class1主窗口小部件(等待光标)时,鼠标光标必须更改。

有什么想法吗?

我可以确认这是一个回归。在OS X 10.8.4上测试。它在问题4.8.5下工作,在问题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"

相关内容

  • 没有找到相关文章

最新更新