翻譯|使用教程|編輯:龔雪|2024-10-31 15:28:54.180|閱讀 139 次
概述:本文中的示例主要演示如何將非Qt UI元素嵌入到Qt應用程序中,歡迎下載最新版組件體驗~
# 界面/圖表報表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
相關鏈接:
Qt 是目前最先進、最完整的跨平臺C++開發工具。它不僅完全實現了一次編寫,所有平臺無差別運行,更提供了幾乎所有開發過程中需要用到的工具。如今,Qt已被運用于超過70個行業、數千家企業,支持數百萬設備及應用。
本文中的示例主要演示如何將非Qt UI元素嵌入到Qt應用程序中。
Qt為Qt Widget和基于Qt Quick的應用程序提供了廣泛的UI控件,但有時可能需要使用來自其他UI工具包的控件,例如平臺的本地UI工具包。
為了集成這些控件,我們建立在Qt的QWindow抽象之上,通過創建原生UI控件的QWindow表示,然后將其嵌入到Qt UI中。以這種方式創建的窗口在Qt中稱為外部窗口,因為它表示由外部(對Qt) UI工具包創建的控件。
Qt技術交流群:166830288 歡迎一起進群討論
要創建QWindow表示,我們使用QWindow::fromWinId(),傳遞對本機窗口句柄的引用,該句柄由不透明的WId類型表示。
每個平臺定義WId不透明類型映射到的本機類型。
結果是一個表示本機窗口句柄的。
注意:Qt在創建外部窗口時不會(獨占)擁有本機窗口句柄,因此應用程序負責在外部QWindow的生命周期內保持本機窗口的激活。
現在在使用() 創建 之前,我們需要一個本機窗口句柄。在本例中,我們將嵌入一個月歷控件,因為大多數平臺在其原生UI工具包中都有它,或者其他隨時可用的控件。下面的代碼片段顯示了如何在每個平臺上創建日歷的細節。
為了確保本機句柄保持激活狀態,并在應用程序退出時正確清理,我們維護了一個清理函數列表,這些函數在從main()返回之前執行。
除了創建本機窗口句柄并將其轉換為QWindow之外,我們還在生成的上設置了最小大小,基于此本機工具包可以告訴我們日歷控件的首選最小大小,這允許Qt正確地布局嵌入的外部窗口。
macOS
Windows
X11
iOS
Android
#include <AppKit/NSDatePicker.h> #include <AppKit/NSLayoutConstraint.h> QWindow *createCalendarWindow() { auto *datePicker = [NSDatePicker new]; cleanupFunctions.push_back([=]{ [datePicker release]; }); datePicker.datePickerStyle = NSDatePickerStyleClockAndCalendar; datePicker.datePickerElements = NSDatePickerElementFlagYearMonthDay; datePicker.drawsBackground = YES; datePicker.dateValue = [NSDate now]; auto *calendarWindow = QWindow::fromWinId(WId(datePicker)); calendarWindow->setMinimumSize(QSizeF::fromCGSize(datePicker.fittingSize).toSize()); return calendarWindow; }
現在我們有了一個外部的QWindow,可以將它嵌入到Qt UI中。在這里有幾個選項,如下所述。
在最底層,我們可以通過QWindow::setParent()將外部窗口嵌入到另一個QWindow中,這種方法讓應用程序開發人員來處理定位、調整大小和管理嵌入子窗口的其他方面,所以我們通常建議不要在這個級別上進行集成,如果可能的話。
在這個例子中,我們首先創建一個最小的容器窗口實現。
class ContainerWindow : public QRasterWindow { protected: bool event(QEvent *event) override { if (event->type() == QEvent::ChildWindowAdded) { auto *childWindow = static_cast<QChildWindowEvent*>(event)->child(); childWindow->resize(childWindow->minimumSize()); setMinimumSize(childWindow->size().grownBy(contentsMargins)); resize(minimumSize()); } return QRasterWindow::event(event); } void showEvent(QShowEvent *) override { findChild<QWindow*>()->setVisible(true); } void resizeEvent(QResizeEvent *) override { auto *containedWindow = findChild<QWindow*>(); containedWindow->setPosition( (width() / 2) - containedWindow->width() / 2, (height() / 2) - containedWindow->height() / 2 ); } void paintEvent(QPaintEvent *) override { QPainter painter(this); painter.fillRect(0, 0, width(), height(), "#00414A"); } };
然后我們就可以重新打開外部窗口。
ContainerWindow window; window.setTitle("Qt Gui"); auto *calendarWindow = createCalendarWindow(); calendarWindow->setParent(&window);
對于建立在Qt Widgets UI堆棧上的應用程序,我們遵循與()相同的方法,通過()創建QWindow的一個QWidget表示。
然后我們可以通過()將這個小部件重命名為另一個小部件,與上面Qt Gui的例子一樣,必須手動管理定位、調整大小等。在本例中,我們傾向于將窗口容器小部件添加到,,這允許我們自動將外部窗口居中于頂級小部件內。
QWidget widget; widget.setPalette(QColor("#CDB0FF")); widget.setWindowTitle("Qt Widgets"); widget.setLayout(new QVBoxLayout); widget.layout()->setContentsMargins(contentsMargins); widget.layout()->setAlignment(Qt::AlignCenter); auto *calendarWidget = QWidget::createWindowContainer(createCalendarWindow()); widget.layout()->addWidget(calendarWidget);
最后,對于構建在Qt Quick UI堆棧上的應用程序,我們使用WindowContainer項來管理外部窗口。
Window { title: "Qt Quick" color: "#2CDE85" required property QtObject calendarWindow; property int contentsMargins: 20 minimumWidth: calendarWindow.minimumWidth + contentsMargins * 2 minimumHeight: calendarWindow.minimumHeight + contentsMargins * 2 WindowContainer { id: calendar window: calendarWindow width: window.minimumWidth height: window.minimumHeight anchors.centerIn: parent } }
在本例中,外部窗口作為上下文屬性公開給QML引擎,但這可以根據應用程序的需要以不同的方式解決。
QQmlApplicationEngine engine; engine.setInitialProperties({{ "calendarWindow", QVariant::fromValue(createCalendarWindow()) }}); engine.loadFromModule("windowembedding", "Main");
本站文章除注明轉載外,均為本站原創或翻譯。歡迎任何形式的轉載,但請務必注明出處、不得修改原文相關鏈接,如果存在內容上的異議請郵件反饋至chenjj@fc6vip.cn
文章轉載自:慧都網