2014-11-15 11 views
8

मैं कुछ प्रस्तुतियों को प्रदर्शित करने के लिए QOpenGLWidget के एक कस्टम उप-वर्ग का उपयोग करता हूं जो एक प्रोजेक्ट पर काम कर रहा हूं। paintGL() विधि के अंत में यह दृश्यमान घटना को ट्रिगर करने के लिए विजेट की update() विधि को कॉल करता है यदि यह दिखाई दे रहा है। अब मैं अपने Ui के लिए एक अतिरिक्त QVTKWidget जोड़ना चाहते हैं और मैं कुछ इस तरह का उपयोग करके ऐसा:एक ही यूआई में QVTKWidget और QOpenGLWidget का उपयोग करना?

QVBoxLayout* layout = findChild<QVBoxLayout*>("layout_simulation"); 
QVTKWidget* widget = new QVTKWidget(); 

// Setup arrow 
vtkSmartPointer<vtkArrowSource> arrowSource = vtkSmartPointer<vtkArrowSource>::New(); 

[more VTK stuff...] 

widget->GetRenderWindow()->AddRenderer(renderer); 
renderer->AddActor(arrowActor); 
renderer->ResetCamera(); 

// Add widget to ui 
layout->addWidget(widget); 

VTK विजेट ui में जोड़ा जाता है और के रूप में इरादा काम कर रहा है। समस्या यह है कि जैसे ही मैं layout->addWidget() विधि का उपयोग करता हूं, मेरे सभी अन्य QOpenGLWidget ऑब्जेक्ट्स काले बदलते हैं और कुछ भी प्रदर्शित नहीं करते हैं। इसके अलावा यह काला VTKRenderer का पृष्ठभूमि रंग नहीं है क्योंकि अन्य विजेट अभी भी काले हैं, भले ही मैं वीटीके विजेट का पृष्ठभूमि रंग बदलूं। मैंने चेक किया और paintGL() अभी भी एक लूप में बुलाया जाता है लेकिन यह कुछ भी प्रदर्शित नहीं करता है। मुझे पूरा यकीन है कि मैंने अपने विजेट सबक्लास में किसी भी खराब ओपनजीएल कोड का उपयोग नहीं किया है, इसलिए मुझे लगता है कि QOpenGLWidget और QVTKWidget के आंतरिक प्रारंभिकरण के साथ इसका कुछ संबंध है। वही होता है यदि मैं सभी वीटीके कॉल छोड़ देता हूं और केवल नव निर्मित QVTKWidget जोड़ता हूं।

मजाकिया बात यह है कि अगर मैं layout->addWidget() कॉल को छोड़ देता हूं, तो वीटीके एक अलग विंडो में रेंडरर खोलता है और सभी ओपनजीएल विजेट बिना किसी समस्या के काम करते हैं। लेकिन निश्चित रूप से मैं अपने यूई में रेंडरर को एम्बेड करना चाहता हूं।

क्या किसी के पास इसका अनुभव है या क्या आपको पता है कि मैंने किसी भी समस्या को हल किया है या क्या कोई आम समस्या है जो इसका कारण बन सकती है?

बीटीडब्लू: मैं अपने QOpenGLWidget सबक्लास के लिए कस्टम शेडर्स के साथ ओपनजीएल 3.3 कोर प्रोफाइल का उपयोग करता हूं।

संपादित करें: मैंने 3.3 कोर प्रोफाइल के लिए अपना अनुरोध हटा दिया और अब यह 4.4 संगतता प्रोफ़ाइल का उपयोग करता है। मुझे लगता है कि यह अब VTKRenderer के समान प्रोफ़ाइल का उपयोग कर रहा है, इसलिए इसे त्रुटि के स्रोत के रूप में अस्वीकार किया जा सकता है।

+0

बग अभी भी VTK 7.1 और क्यूटी 5.7 में मौजूद। मेरे लिए यह सिर्फ काला नहीं है, यह दुर्घटनाग्रस्त हो जाता है। –

+0

क्या कोई इसे वीटीके बग ट्रैकर की रिपोर्ट करता है? –

+0

क्षमा करें, मैंने नहीं किया।मुझे लगता है कि हाल ही में क्यूटी ओपनजीएल मानकों का उपयोग कर QVTKWidget का पूर्ण पुनर्मूल्यांकन करने में भी समझदारी होगी ... – w1th0utnam3

उत्तर

11

इसलिए मुझे नहीं पता कि वास्तव में समस्या का कारण क्या है लेकिन मैंने इसे हल किया। सबसे पहले मुझे पता चला कि वीटीके के लिए एक दूसरी विजेट क्लास है जिसे QVTKWidget2 कहा जाता है लेकिन दुर्भाग्य से यह क्यूटी 5.4 के लिए पूरी तरह से संगत नहीं है क्योंकि यह पुराने क्यूजीएल कक्षाओं (जैसे QGLWidgetQOpenGLWidget के बजाय) का उपयोग करता है। इसलिए मैंने QOpenGLWidget के उप-वर्ग के रूप में इसे फिर से कार्यान्वित करना शुरू किया जो काफी सीधे था। नीचे मेरी कक्षा QVTKWidget3 के लिए स्रोत फ़ाइलें हैं जो रुचि रखने वाले किसी भी व्यक्ति के लिए Qt 5.4 के साथ काम करती हैं। मैंने केवल सीमित परीक्षण किया (क्योंकि मैं अभी भी वीटीके सीख रहा हूं) लेकिन एक सरल क्षेत्र जैसे प्रदर्शन के उदाहरण।

फिर से: यह केवल क्यूटी 5.4 (बीटा) के साथ काम करता है क्योंकि पुराना संस्करण QOpenGLWidget क्लास प्रदान नहीं करता है!

हैडर फ़ाइल: qvtkwidget3.h

#ifndef QVTKWIDGET3_H 
#define QVTKWIDGET3_H 

#include "vtkSmartPointer.h" 
#include "vtkGenericOpenGLRenderWindow.h" 
#include "vtkEventQtSlotConnect.h" 

#include "QVTKInteractorAdapter.h" 
#include "QVTKInteractor.h" 

#include <QOpenGLWidget> 
#include <QSurfaceFormat> 

class QVTKWidget3 : public QOpenGLWidget 
{ 
    Q_OBJECT 

public: 
    QVTKWidget3(QWidget *parent = NULL, Qt::WindowFlags f = 0, QSurfaceFormat format = QSurfaceFormat::defaultFormat()); 
    virtual ~QVTKWidget3(); 

    //! Set a custom render window 
    virtual void SetRenderWindow(vtkGenericOpenGLRenderWindow*); 
    //! Returns the curren render window (creates one if none exists) 
    virtual vtkGenericOpenGLRenderWindow* GetRenderWindow(); 

    //! Returns interactor of the current render window 
    virtual QVTKInteractor* GetInteractor(); 

public slots: 
    //! Slot to make this vtk render window current 
    virtual void MakeCurrent(); 
    //! Slot called when vtk wants to know if the context is current 
    virtual void IsCurrent(vtkObject* caller, unsigned long vtk_event, void* client_data, void* call_data); 
    //! Slot called when vtk wants to frame the window 
    virtual void Frame(); 
    //! Slot called when vtk wants to start the render 
    virtual void Start(); 
    //! Slot called when vtk wants to end the render 
    virtual void End(); 
    //! Slot called when vtk wants to know if a window is direct 
    virtual void IsDirect(vtkObject* caller, unsigned long vtk_event, void* client_data, void* call_data); 
    //! Slot called when vtk wants to know if a window supports OpenGL 
    virtual void SupportsOpenGL(vtkObject* caller, unsigned long vtk_event, void* client_data, void* call_data); 

protected: 
    //! Initialize handler 
    virtual void initializeGL(); 
    //! Paint handler 
    virtual void paintGL(); 
    //! Resize handler 
    virtual void resizeGL(int, int); 
    //! Move handler 
    virtual void moveEvent(QMoveEvent* event); 

    virtual void mousePressEvent(QMouseEvent* event); 
    virtual void mouseMoveEvent(QMouseEvent* event); 
    virtual void mouseReleaseEvent(QMouseEvent* event); 
    virtual void keyPressEvent(QKeyEvent* event); 
    virtual void keyReleaseEvent(QKeyEvent* event); 
    virtual void enterEvent(QEvent*); 
    virtual void leaveEvent(QEvent*); 
    virtual void wheelEvent(QWheelEvent*); 

    virtual void contextMenuEvent(QContextMenuEvent*); 
    virtual void dragEnterEvent(QDragEnterEvent*); 
    virtual void dragMoveEvent(QDragMoveEvent*); 
    virtual void dragLeaveEvent(QDragLeaveEvent*); 
    virtual void dropEvent(QDropEvent*); 

    virtual bool focusNextPrevChild(bool); 

    // Members 
    vtkGenericOpenGLRenderWindow* m_renWin; 
    QVTKInteractorAdapter* m_irenAdapter; 
    vtkSmartPointer<vtkEventQtSlotConnect> m_connect; 

private: 
    //! unimplemented operator= 
    QVTKWidget3 const& operator=(QVTKWidget3 const&); 
    //! unimplemented copy 
    QVTKWidget3(const QVTKWidget3&); 
}; 

#endif // QVTKWIDGET3_H 

स्रोत फ़ाइल: qvtkwidget3.cpp

#include "qvtkwidget3.h" 

#include "vtkRenderWindowInteractor.h" 
#include "vtkInteractorStyle.h" 
#include "vtkInteractorStyleTrackballCamera.h" 

#include <QResizeEvent> 

QVTKWidget3::QVTKWidget3(QWidget *parent, Qt::WindowFlags f, QSurfaceFormat format) 
    : QOpenGLWidget(parent, f) 
    , m_renWin(nullptr) 
{ 
    // VTK requires a compatibility profile 
    format.setProfile(QSurfaceFormat::CompatibilityProfile); 
    setFormat(format); 

    // Initialize interactors 
    m_irenAdapter = new QVTKInteractorAdapter(this); 
    m_connect = vtkSmartPointer<vtkEventQtSlotConnect>::New(); 
} 

// Destructor 
QVTKWidget3::~QVTKWidget3() 
{ 
    // Following line is not needed. 
    // get rid of the VTK window 
    // this->SetRenderWindow(NULL); 
} 

// GetRenderWindow 
vtkGenericOpenGLRenderWindow* QVTKWidget3::GetRenderWindow() 
{ 
    if (this->m_renWin == nullptr) 
    { 
     // create a default vtk window 
     vtkGenericOpenGLRenderWindow* win = vtkGenericOpenGLRenderWindow::New(); 
     this->SetRenderWindow(win); 
    } 

    return this->m_renWin; 
} 

// SetRenderWindow 
void QVTKWidget3::SetRenderWindow(vtkGenericOpenGLRenderWindow* w) 
{ 
    // do nothing if we don't have to 
    if(w == this->m_renWin) { 
     return; 
    } 

    // unregister previous window 
    if(this->m_renWin != nullptr) { 
     this->m_renWin->Finalize(); 
     this->m_renWin->SetMapped(0); 

     m_connect->Disconnect(m_renWin, vtkCommand::WindowMakeCurrentEvent, this, SLOT(MakeCurrent())); 
     m_connect->Disconnect(m_renWin, vtkCommand::WindowIsCurrentEvent, this, SLOT(IsCurrent(vtkObject*, unsigned long, void*, void*))); 
     m_connect->Disconnect(m_renWin, vtkCommand::WindowFrameEvent, this, SLOT(Frame())); 
     m_connect->Disconnect(m_renWin, vtkCommand::StartEvent, this, SLOT(Start())); 
     m_connect->Disconnect(m_renWin, vtkCommand::EndEvent, this, SLOT(End())); 
     m_connect->Disconnect(m_renWin, vtkCommand::WindowIsDirectEvent, this, SLOT(IsDirect(vtkObject*, unsigned long, void*, void*))); 
     m_connect->Disconnect(m_renWin, vtkCommand::WindowSupportsOpenGLEvent, this, SLOT(SupportsOpenGL(vtkObject*, unsigned long, void*, void*))); 
    } 

    // now set the window 
    this->m_renWin = w; 

    if(this->m_renWin != nullptr) { 
     // if it is mapped somewhere else, unmap it 
     this->m_renWin->Finalize(); 
     this->m_renWin->SetMapped(1); 

     // tell the vtk window what the size of this window is 
     this->m_renWin->SetSize(this->width(), this->height()); 
     this->m_renWin->SetPosition(this->x(), this->y()); 

     // if an interactor wasn't provided, we'll make one by default 
     if(this->m_renWin->GetInteractor() == NULL) 
     { 
      // create a default interactor 
      QVTKInteractor* iren = QVTKInteractor::New(); 
      iren->SetUseTDx(false); 
      this->m_renWin->SetInteractor(iren); 
      iren->Initialize(); 

      // now set the default style 
      vtkInteractorStyle* s = vtkInteractorStyleTrackballCamera::New(); 
      iren->SetInteractorStyle(s); 

      iren->Delete(); 
      s->Delete(); 
     } 

     // tell the interactor the size of this window 
     this->m_renWin->GetInteractor()->SetSize(this->width(), this->height()); 

     m_connect->Connect(m_renWin, vtkCommand::WindowMakeCurrentEvent, this, SLOT(MakeCurrent())); 
     m_connect->Connect(m_renWin, vtkCommand::WindowIsCurrentEvent, this, SLOT(IsCurrent(vtkObject*, unsigned long, void*, void*))); 
     m_connect->Connect(m_renWin, vtkCommand::WindowFrameEvent, this, SLOT(Frame())); 
     m_connect->Connect(m_renWin, vtkCommand::StartEvent, this, SLOT(Start())); 
     m_connect->Connect(m_renWin, vtkCommand::EndEvent, this, SLOT(End())); 
     m_connect->Connect(m_renWin, vtkCommand::WindowIsDirectEvent, this, SLOT(IsDirect(vtkObject*, unsigned long, void*, void*))); 
     m_connect->Connect(m_renWin, vtkCommand::WindowSupportsOpenGLEvent, this, SLOT(SupportsOpenGL(vtkObject*, unsigned long, void*, void*))); 
    } 
} 

// GetInteractor 
QVTKInteractor* QVTKWidget3::GetInteractor() 
{ 
    return QVTKInteractor::SafeDownCast(this->GetRenderWindow()->GetInteractor()); 
} 

// Initialize 
void QVTKWidget3::initializeGL() 
{ 
    if(this->m_renWin == nullptr) { 
     return; 
    } 

    this->m_renWin->OpenGLInitContext(); 
} 

// Paint 
void QVTKWidget3::paintGL() 
{ 
    vtkRenderWindowInteractor* iren = nullptr; 
    if(this->m_renWin != nullptr) { 
     iren = this->m_renWin->GetInteractor(); 
    } 

    if(iren == nullptr || !iren->GetEnabled()) { 
     return; 
    } 

    iren->Render(); 
} 

// Resize 
void QVTKWidget3::resizeGL(int w, int h) 
{ 
    if(this->m_renWin == nullptr) { 
     return; 
    } 

    this->m_renWin->SetSize(w,h); 

    // and update the interactor 
    if(this->m_renWin->GetInteractor() != NULL) { 
     QResizeEvent e(QSize(w,h), QSize()); 
     m_irenAdapter->ProcessEvent(&e, this->m_renWin->GetInteractor()); 
    } 
} 

// Move 
void QVTKWidget3::moveEvent(QMoveEvent* e) 
{ 
    QWidget::moveEvent(e); 

    if(this->m_renWin == nullptr) { 
     return; 
    } 

    this->m_renWin->SetPosition(this->x(), this->y()); 
} 


// -------- 
// Slots 
// -------- 

void QVTKWidget3::Start() 
{ 
    makeCurrent(); 
    m_renWin->PushState(); 
    m_renWin->OpenGLInitState(); 
} 

void QVTKWidget3::End() 
{ 
    m_renWin->PopState(); 
} 

void QVTKWidget3::MakeCurrent() 
{ 
    return; 
    // Automaticly handled by QOpenGLWidget 
    // this->makeCurrent(); 
} 

void QVTKWidget3::IsCurrent(vtkObject*, unsigned long, void*, void* call_data) 
{ 
    bool* ptr = reinterpret_cast<bool*>(call_data); 
    *ptr = (int)true; 
} 

void QVTKWidget3::IsDirect(vtkObject*, unsigned long, void*, void* call_data) 
{ 
    int* ptr = reinterpret_cast<int*>(call_data); 
    *ptr = (int)true; 
} 

void QVTKWidget3::SupportsOpenGL(vtkObject*, unsigned long, void*, void* call_data) 
{ 
    int* ptr = reinterpret_cast<int*>(call_data); 
    *ptr = (int)true; 
} 

void QVTKWidget3::Frame() 
{ 
    if(m_renWin->GetSwapBuffers()) { 
     this->update(); 
    } 

    // This callback will call swapBuffers() for us 
    // because sometimes VTK does a render without coming through this paintGL() 

    // FOLLOWING NOT TESTED FOR QOPENGLWIDGET 
    // if you want paintGL to always be called for each time VTK renders 
    // 1. turn off EnableRender on the interactor, 
    // 2. turn off SwapBuffers on the render window, 
    // 3. add an observer for the RenderEvent coming from the interactor 
    // 4. implement the callback on the observer to call updateGL() on this widget 
    // 5. overload QVTKWidget3::paintGL() to call m_renWin->Render() instead iren->Render() 
} 

// ---------------------- 
// Interaction handlers 
// ---------------------- 

/*! handle mouse press event 
*/ 
void QVTKWidget3::mousePressEvent(QMouseEvent* e) 
{ 
    if(this->m_renWin) 
    { 
     m_irenAdapter->ProcessEvent(e, this->m_renWin->GetInteractor()); 
    } 

} 

/*! handle mouse move event 
*/ 
void QVTKWidget3::mouseMoveEvent(QMouseEvent* e) 
{ 
    if(this->m_renWin) 
    { 
     m_irenAdapter->ProcessEvent(e, this->m_renWin->GetInteractor()); 
    } 
} 

/*! handle enter event 
*/ 
void QVTKWidget3::enterEvent(QEvent* e) 
{ 
    if(this->m_renWin) 
    { 
     m_irenAdapter->ProcessEvent(e, this->m_renWin->GetInteractor()); 
    } 
} 

/*! handle leave event 
*/ 
void QVTKWidget3::leaveEvent(QEvent* e) 
{ 
    if(this->m_renWin) 
    { 
     m_irenAdapter->ProcessEvent(e, this->m_renWin->GetInteractor()); 
    } 
} 

/*! handle mouse release event 
*/ 
void QVTKWidget3::mouseReleaseEvent(QMouseEvent* e) 
{ 
    if(this->m_renWin) 
    { 
     m_irenAdapter->ProcessEvent(e, this->m_renWin->GetInteractor()); 
    } 
} 

/*! handle key press event 
*/ 
void QVTKWidget3::keyPressEvent(QKeyEvent* e) 
{ 
    if(this->m_renWin) 
    { 
     m_irenAdapter->ProcessEvent(e, this->m_renWin->GetInteractor()); 
    } 
} 

/*! handle key release event 
*/ 
void QVTKWidget3::keyReleaseEvent(QKeyEvent* e) 
{ 
    if(this->m_renWin) 
    { 
     m_irenAdapter->ProcessEvent(e, this->m_renWin->GetInteractor()); 
    } 
} 

void QVTKWidget3::wheelEvent(QWheelEvent* e) 
{ 
    if(this->m_renWin) 
    { 
     m_irenAdapter->ProcessEvent(e, this->m_renWin->GetInteractor()); 
    } 
} 

void QVTKWidget3::contextMenuEvent(QContextMenuEvent* e) 
{ 
    if(this->m_renWin) 
    { 
     m_irenAdapter->ProcessEvent(e, this->m_renWin->GetInteractor()); 
    } 
} 

void QVTKWidget3::dragEnterEvent(QDragEnterEvent* e) 
{ 
    if(this->m_renWin) 
    { 
     m_irenAdapter->ProcessEvent(e, this->m_renWin->GetInteractor()); 
    } 
} 

void QVTKWidget3::dragMoveEvent(QDragMoveEvent* e) 
{ 
    if(this->m_renWin) 
    { 
     m_irenAdapter->ProcessEvent(e, this->m_renWin->GetInteractor()); 
    } 
} 

void QVTKWidget3::dragLeaveEvent(QDragLeaveEvent* e) 
{ 
    if(this->m_renWin) 
    { 
     m_irenAdapter->ProcessEvent(e, this->m_renWin->GetInteractor()); 
    } 
} 

void QVTKWidget3::dropEvent(QDropEvent* e) 
{ 
    if(this->m_renWin) 
    { 
     m_irenAdapter->ProcessEvent(e, this->m_renWin->GetInteractor()); 
    } 
} 

bool QVTKWidget3::focusNextPrevChild(bool) 
{ 
    return false; 
} 
+2

मुझे vtk-6.2 और qt-5.2.1 के साथ एक ही समस्या का सामना करना पड़ रहा है। कुछ मामूली अनुकूलन ('QGLWidget' का उपयोग करने के लिए) के साथ आपके समाधान ने मेरे लिए काम किया। धन्यवाद! – taketwo

+2

रिकॉर्ड के लिए: बग अभी भी QT5.5 और VTK7 के साथ मौजूद है ... और आपका समाधान अभी भी काम करता है। बहुत बढ़िया! – GPMueller

संबंधित मुद्दे