2013-08-26 1 views
0

더 큰 응용 프로그램에서 발생하는 문제를 보여주기 위해 간단한 프로젝트를 만들었습니다.
그래서 두 개의 버튼이있는 메인 윈도우를 만듭니다. 나는 2 개의 버튼과 QGL 뷰로 QWidget을 상속받은 클래스를 만든다.
문제는 외관상으로는 그리고 내가 찾지 못한 어떤 이유로이 QGL 뷰를 생성하면 뷰의 일부 이벤트, 특히 마우스 이벤트를 차단한다는 것입니다. 아래 코드에서 마우스 커서가 주 윈도우 버튼에서 잘 바뀌지 만 버튼과 마우스 클래스의 주 위젯은 감지되지 않습니다 (커서는 화살표에서 손으로 바뀌고 대기합니다). 실제 응용 프로그램, 그것은 간단한 호버 이벤트보다 더 심각한).
정확하게이 문제는 Windows가 아닌 Mac 10.6 이상에서만 나타납니다. 나는 Qt 5.1을 사용한다. 여기 QGL 때문에 마우스 이벤트가 차단되었습니다.

코드이다

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에서 class1없이 myGLView 인스턴스를 직접 생성하면 작동합니다. 하지만 필자는 차이점보기를 생성해야하며 모든 내용이 메인 윈도우에서 생성되는 것은 아닙니다.
부모님이나 자식에게 이벤트가 전달 될 때보기, 그 부모 또는 그와 비슷한 것을 만드는 방식에 문제가 있습니다. 그래서 문제는 그 것과 링크되어 있다고 생각합니다. 잘 작동하면 마우스가 버튼 1과 2 (손 모양 커서) 위로 이동하고 class1 메인 위젯 (커서 대기 중)을 가리키면 마우스 커서가 변경되어야합니다.

아이디어가 있으십니까?

+0

이 가장 가능성이 Qt는 버그 게시하려면 다음을 생산하는 알 온전한 단일 파일 테스트 케이스이지만, 당신이 가지고있는 테스트 케이스는 거대하다. 최대로 몇 줄 줄여야합니다! –

+0

테스트 케이스가 단순화되었습니다. 몇 줄의 라인에서 어렵습니다. 내가 게시 한 코드가 제가 할 수있는 최선입니다. – SteveTJS

+0

아래에 표시된대로, 당신이 당신을 의논하지 않는 경우에 60의 선은 길 수있다.pro file :) –

답변

0

회귀임을 확인할 수 있습니다. OS X 10.8.4에서 테스트되었습니다. Qt 4.8.5에서 작동하고 Qt 5.1.0에서는 작동하지 않습니다. 버그로보고해야합니다. 다음은 당신에 유래하는 :)

//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" 
+0

답변과 간단한 코드에 감사드립니다. 나는 Qt 4.8.5에 대한 테스트를했고 실제로 작동한다. 당신이 제안한대로 Qt 버그 리포트의 버그를보고했습니다. – SteveTJS