2016-08-05 4 views
9

मुझे एक मूल ओएसएक्स विंडो में एक QML दृश्य डालने का प्रयास करने में समस्या आ रही है। मुझे पता है कि यह संभव है, लेकिन मुझे नहीं पता कि मैं क्या गलत कर रहा हूं।एक मूल विंडो में एक QML दृश्य को एम्बेड करने के लिए कैसे करें

असल में, मेरा लक्ष्य है, एक देशी NSView * को तब एक क्यूएमएल आधारित विजेट एम्बेड करने के लिए दिया गया है। समस्या यह है कि मुझे यह इंगित करने के लिए मिलता है कि यह वास्तव में दृश्य के अंदर qml को प्रस्तुत करता है लेकिन यह पक्ष में एक अतिरिक्त पारदर्शी विंडो बनाता है और ऐसा लगता है कि यह क्यूएमएल दृश्य को ठीक से नहीं लेता है।

यहाँ कोड है कि मैं का उपयोग कर रहा है (सभी मेमोरी लीक पर ध्यान न दें):

@interface AppDelegate() 
-(void)processEvents; 

@property(nonatomic) NSTimer* timer; 
@property(nonatomic) QApplication* qt; 
@end 

@implementation AppDelegate 

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification 
{ 
    // Insert code here to initialize your application 
    NSWindow* window = [[[NSApplication sharedApplication] windows] objectAtIndex:0]; 
    NSView *view = [window contentView]; 
    assert(view); 

    char* test[0]; 
    int count = 0; 

    QApplication::instance()->setAttribute(Qt::AA_MacPluginApplication); 
    _qt = new QApplication(count, test); 

    QMacNativeWidget* native = new QMacNativeWidget(view); 
    assert(native); 

    QQuickWidget* qml = new QQuickWidget(native); 
    qml->setSource(QUrl(QStringLiteral("main.qml"))); 

    QVBoxLayout* layout = new QVBoxLayout(); 
    layout->addWidget(qml); 

    native->setLayout(layout); 

    qml->show(); 
    native->show(); 


    NSView* qmlView = (NSView*)native->winId(); 
    [view addSubview:qmlView]; 

    _timer = [NSTimer scheduledTimerWithTimeInterval:0.03 target:self selector:@selector(processEvents) userInfo:nil repeats:YES]; 
} 

- (void)applicationWillTerminate:(NSNotification *)aNotification 
{ 
    // Insert code here to tear down your application 
    [_timer invalidate]; 
    _qt->quit(); 

} 

-(void)processEvents 
{ 
    _qt->processEvents(); 
    _qt->sendPostedEvents(0,-1); 
} 

@end 

और यहाँ सरल qml है:

import QtQuick 2.7 

Item 
{ 
    visible: true 
    x: 0; 
    y: 0; 
    width: 100 
    height: 100 
    Rectangle 
    { 
     anchors.fill: parent 
     color: 'blue' 
     MouseArea 
     { 
      anchors.fill: parent 
      onClicked: 
      { 
       console.log(parent.color); 
       if(parent.color == '#0000ff') 
        parent.color = 'green'; 
       else 
        parent.color = 'blue'; 
      } 
     } 
    } 
} 

उत्तर

1

QQuickWidget में अन्य विजेट सामग्री के साथ अपनी सामग्री composities थोड़ा सा जटिल तरीका, जिसमें फ्रेमबफर और ऑफस्क्रीन विंडो शामिल है, जो मुझे संदेह है कि आप जो अजीब परिणाम देखते हैं उसे समझा सकते हैं - मैं प्लगइन की स्थिति में काम करने की अपेक्षा नहीं करता।

सबसे आसान विकल्प एक QWidget अपने QMacNativeWidget करने के लिए आप माता-पिता कर सकते हैं में QWindow चालू करने के लिए createWindowContainer के साथ एक QQuickWindow (या QQuickView) का उपयोग किया जाएगा।

हालांकि, मुझे लगता है कि सबसे मजबूत दृष्टिकोण विजेट और खिड़कियों को पूरी तरह से अनदेखा करना होगा, और QQuickRenderControl और NSOpenGLView का उपयोग करके फ्रेमबफर स्तर पर एकीकृत करना होगा। यह कोड करने के लिए और अधिक काम है लेकिन NSView पदानुक्रम को सीधे रखता है, और सर्वोत्तम संभव प्रदर्शन देना चाहिए। आप या तो देशी ओपनजीएल व्यू में सीधे प्रस्तुत कर सकते हैं (जिसके लिए मूल संदर्भ से QOpenGLContext बनाना संभव है, क्यूटी 5.4 के बाद से संभव है), या QtQuick और NSOpenGLContext के बीच साझा किए गए बनावट का उपयोग करके फ्रेमबफर में।

+0

उत्तर देने के लिए समय निकालने के लिए बहुत बहुत धन्यवाद। मैं इन विकल्पों का शोध करूंगा और देख सकता हूं कि वे काम करते हैं या नहीं। इस बीच, क्या आप मुझे कहीं भी लागू एक उदाहरण के लिए इंगित करने में सक्षम होंगे? – bitwise

+0

'createWindowContainer' के लिए बस दस्तावेज़ों को देखें - यह एक' QQuickWindow' ले जाएगा और इसे विजेट में लपेट देगा। यह विभिन्न कार्यान्वयन विकल्पों के कारण QQuickWidget की तुलना में एक प्लगइन परिदृश्य में बेहतर काम करेगा। –

+0

QQuickRenderControl के लिए, 'QQuickRenderControl' उदाहरण देखें जो क्यूटी के साथ जहाजों - आपको 'NSOpenGLView' के साथ उस उदाहरण में' विंडोस्लिंग थ्रेडेड 'को प्रतिस्थापित करने की आवश्यकता है, और' QOpenGLContext' में संबंधित 'openGLContext' को रेंडर के साथ उपयोग करने के लिए' नियंत्रण। –

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