簡體   English   中英

如何將QML視圖嵌入到本機窗口中

[英]How to embed a QML view into a native window

我在嘗試將QML視圖插入本機OSX窗口時遇到問題。 我知道這是可能的,但我不知道我做錯了什么。

基本上,我的目標是,給定一個原生的NSView *然后嵌入一個基於QML的小部件。 問題是,我確定它確實在視圖中渲染了qml,但是它創建了一個額外的透明窗口,它似乎沒有正確地重繪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';
            }
        }
    }
}

QQuickWidget以一種稍微復雜的方式將其內容與其他小部件內容相結合,包括幀緩沖和屏幕外窗口,我懷疑這可能解釋了你看到的奇怪結果 - 我不希望它在插件情況下工作。

最簡單的選擇是使用帶有createWindowContainerQQuickWindow (或QQuickView )將QWindow轉換為QWidget您可以將其作為QWindowQMacNativeWidget

但是,我認為最強大的方法是完全忽略小部件和窗口,並使用QQuickRenderControlNSOpenGLView在幀緩沖級別進行NSOpenGLView 這是編寫代碼的更多工作,但保持NSView層次結構簡單明了,並且應該提供最佳性能。 您可以直接渲染到本機OpenGL視圖(這需要從本機上下文創建QOpenGLContext ,可能從Qt 5.4開始),或者使用QtQuick和NSOpenGLContext之間共享的紋理進入幀緩沖區。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM