0

我创建了一个简单的项目来展示我在更大的应用程序中遇到的问题。
因此,我创建了一个带有 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

主窗口.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;
}

类1.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

类1.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;
}

主窗口.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>

类1.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 主小部件(等待光标)。

有任何想法吗?

4

1 回答 1

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"
于 2013-08-26T15:58:47.560 回答