翻譯|使用教程|編輯:龔雪|2024-10-31 15:28:54.180|閱讀 139 次
概述:本文中的示例主要演示如何將非Qt UI元素嵌入到Qt應(yīng)用程序中,歡迎下載最新版組件體驗(yàn)~
# 界面/圖表報(bào)表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
相關(guān)鏈接:
Qt 是目前最先進(jìn)、最完整的跨平臺(tái)C++開發(fā)工具。它不僅完全實(shí)現(xiàn)了一次編寫,所有平臺(tái)無差別運(yùn)行,更提供了幾乎所有開發(fā)過程中需要用到的工具。如今,Qt已被運(yùn)用于超過70個(gè)行業(yè)、數(shù)千家企業(yè),支持?jǐn)?shù)百萬設(shè)備及應(yīng)用。
本文中的示例主要演示如何將非Qt UI元素嵌入到Qt應(yīng)用程序中。
Qt為Qt Widget和基于Qt Quick的應(yīng)用程序提供了廣泛的UI控件,但有時(shí)可能需要使用來自其他UI工具包的控件,例如平臺(tái)的本地UI工具包。
為了集成這些控件,我們建立在Qt的QWindow抽象之上,通過創(chuàng)建原生UI控件的QWindow表示,然后將其嵌入到Qt UI中。以這種方式創(chuàng)建的窗口在Qt中稱為外部窗口,因?yàn)樗硎居赏獠浚▽?duì)Qt) UI工具包創(chuàng)建的控件。
Qt技術(shù)交流群:166830288 歡迎一起進(jìn)群討論
要創(chuàng)建QWindow表示,我們使用QWindow::fromWinId(),傳遞對(duì)本機(jī)窗口句柄的引用,該句柄由不透明的WId類型表示。
每個(gè)平臺(tái)定義WId不透明類型映射到的本機(jī)類型。
結(jié)果是一個(gè)表示本機(jī)窗口句柄的。
注意:Qt在創(chuàng)建外部窗口時(shí)不會(huì)(獨(dú)占)擁有本機(jī)窗口句柄,因此應(yīng)用程序負(fù)責(zé)在外部QWindow的生命周期內(nèi)保持本機(jī)窗口的激活。
現(xiàn)在在使用() 創(chuàng)建 之前,我們需要一個(gè)本機(jī)窗口句柄。在本例中,我們將嵌入一個(gè)月歷控件,因?yàn)榇蠖鄶?shù)平臺(tái)在其原生UI工具包中都有它,或者其他隨時(shí)可用的控件。下面的代碼片段顯示了如何在每個(gè)平臺(tái)上創(chuàng)建日歷的細(xì)節(jié)。
為了確保本機(jī)句柄保持激活狀態(tài),并在應(yīng)用程序退出時(shí)正確清理,我們維護(hù)了一個(gè)清理函數(shù)列表,這些函數(shù)在從main()返回之前執(zhí)行。
除了創(chuàng)建本機(jī)窗口句柄并將其轉(zhuǎn)換為QWindow之外,我們還在生成的上設(shè)置了最小大小,基于此本機(jī)工具包可以告訴我們?nèi)諝v控件的首選最小大小,這允許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; }
現(xiàn)在我們有了一個(gè)外部的QWindow,可以將它嵌入到Qt UI中。在這里有幾個(gè)選項(xiàng),如下所述。
在最底層,我們可以通過QWindow::setParent()將外部窗口嵌入到另一個(gè)QWindow中,這種方法讓應(yīng)用程序開發(fā)人員來處理定位、調(diào)整大小和管理嵌入子窗口的其他方面,所以我們通常建議不要在這個(gè)級(jí)別上進(jìn)行集成,如果可能的話。
在這個(gè)例子中,我們首先創(chuàng)建一個(gè)最小的容器窗口實(shí)現(xiàn)。
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);
對(duì)于建立在Qt Widgets UI堆棧上的應(yīng)用程序,我們遵循與()相同的方法,通過()創(chuàng)建QWindow的一個(gè)QWidget表示。
然后我們可以通過()將這個(gè)小部件重命名為另一個(gè)小部件,與上面Qt Gui的例子一樣,必須手動(dòng)管理定位、調(diào)整大小等。在本例中,我們傾向于將窗口容器小部件添加到,,這允許我們自動(dòng)將外部窗口居中于頂級(jí)小部件內(nèi)。
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);
最后,對(duì)于構(gòu)建在Qt Quick UI堆棧上的應(yīng)用程序,我們使用WindowContainer項(xiàng)來管理外部窗口。
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引擎,但這可以根據(jù)應(yīng)用程序的需要以不同的方式解決。
QQmlApplicationEngine engine; engine.setInitialProperties({{ "calendarWindow", QVariant::fromValue(createCalendarWindow()) }}); engine.loadFromModule("windowembedding", "Main");
本站文章除注明轉(zhuǎn)載外,均為本站原創(chuàng)或翻譯。歡迎任何形式的轉(zhuǎn)載,但請(qǐng)務(wù)必注明出處、不得修改原文相關(guān)鏈接,如果存在內(nèi)容上的異議請(qǐng)郵件反饋至chenjj@fc6vip.cn
文章轉(zhuǎn)載自:慧都網(wǎng)