bit*_*ise 9 cocoa qt qml qquickwidget qquickview
我在尝试将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
Run Code Online (Sandbox Code Playgroud)
这是简单的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';
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
QQuickWidget以稍微复杂的方式将其内容与其他小部件内容组合,涉及帧缓冲区和屏幕外窗口,我怀疑这可能会解释您看到的奇怪结果 - 我不希望它在插件情况下工作。
最简单的选择是使用QQuickWindow( 或QQuickView) withcreateWindowContainer将 变为您可以QWindow作为.QWidgetQMacNativeWidget
然而,我认为最可靠的方法是完全忽略小部件和窗口,并在帧缓冲区级别集成,使用QQuickRenderControl和NSOpenGLView. 这需要更多的编码工作,但可以保持 NSView 层次结构简单,并且应该提供最佳的性能。您可以直接渲染到本机 OpenGL 视图中(这需要QOpenGLContext从本机上下文创建,从 Qt 5.4 开始可能),或者使用 QtQuick 和NSOpenGLContext.