Qt5। QML में QWidget ऑब्जेक्ट एम्बेड करें




(5)

मैं Qt5 बीटा का उपयोग कर रहा हूं और QWidget- आधारित ऑब्जेक्ट को QML में एम्बेड करने का प्रयास कर रहा हूं। लक्ष्य क्यूएमएल जितना संभव हो उतना उपयोग करना है, और केवल QWidget ऑब्जेक्ट्स का उपयोग करें जहां QML ऐसा नहीं करता जो मुझे चाहिए। मुझे Qt4.7 के लिए यह कैसे करना है, यह बताते हुए एक लिंक मिला, लेकिन मुझे यह जानकारी नहीं मिली है कि Qt5 में इसे कैसे किया जाए।

http://doc.qt.digia.com/4.7/declarative-cppextensions-qwidgets.html

वही उदाहरण क्यूटी 5 उदाहरण फ़ोल्डर में भी उपलब्ध है:

उदाहरण \ qtquick1 \ कथात्मक \ cppextensions \ qwidgets

दुर्भाग्यवश, यह उदाहरण QtQuick 2 के बजाय QtQuick 1 का उपयोग करता है, और मैं Qt5 की नई सुविधाओं का उपयोग करना चाहता हूं। मैं वास्तव में एक qwt विजेट एम्बेड करना चाहता हूं, लेकिन पहले चरण के रूप में मुझे किसी भी साधारण QWidget- आधारित ऑब्जेक्ट को एम्बेड करने में खुशी होगी।

क्या कोई मुझे Qt5 / QtQuick 2 के तहत काम करने का उदाहरण प्राप्त करने में मदद कर सकता है?


अनुशंसित दृष्टिकोण QWidget आधारित एप्लिकेशन के साथ रहना और QWidget :: createWindowContainer का उपयोग कर QML भागों को एम्बेड करना है।


क्यूटी क्विक 2 जीपीयू पर कुशल प्रतिपादन के लिए एक दृश्य ग्राफ का उपयोग करता है। दुर्भाग्यवश यह क्लासिक विजेट को दृश्य में एम्बेड करना असंभव बनाता है। QGraphicsProxyWidget की मदद से ऐसे विजेट एम्बेड करने का पुराना तरीका केवल क्यूटी क्विक 1 के साथ काम करता है, क्योंकि आंतरिक रूप से यह सभी भारी उठाने के लिए QGraphicsView का उपयोग करता है और QGraphicsProxyWidget इसका उपयोग करने के लिए किया जाता है।

अब तक क्लासिक QWidgets को उस दृश्य ग्राफ में एम्बेड करने में सक्षम करने की कोई योजना नहीं है जिसे मैं जानता हूं। मुझे लगता है कि यह बदलने की संभावना नहीं है, क्योंकि क्यूपेन्टर की अवधारणाएं, क्लासिक विगेट्स के लिए उपयोग की जाने वाली पेंटिंग फ्रेमवर्क, और नया दृश्य ग्राफ एक-दूसरे के साथ अच्छा नहीं खेलता है।

क्यूएमएल की जरूरतों के लिए विशेष रूप से तैयार किए गए नए विजेट्स को विकसित करने के कुछ प्रयास हैं, लेकिन इनमें से कोई भी क्लासिक विजेट्स के रूप में शक्तिशाली और परिपक्व नहीं है। सबसे प्रमुख लोग क्यूएमएल क्विक कंट्रोल हैं , जो कि संस्करण 5.1 के बाद क्यूटी के साथ बंडल किए गए हैं।

यदि आप वास्तव में क्यूडब्ल्यूटी पर निर्भर हैं तो मेरी सलाह अब क्यूटी क्विक 1.1 के साथ रहना होगा। यह अभी भी आपके जैसे मामलों के लिए क्यूटी 5 के साथ बंडल किया गया है। इस तरह आप नए दृश्य ग्राफ का लाभ नहीं उठाएंगे, हालांकि।


Here बताया गया है कि QML आधारित लेआउट पर QComboBox को कैसे जोड़ना है। सोचो कि आपके मामले के लिए अच्छा उदाहरण होगा। (क्यूटी 5.9 में मूल कॉम्बोबॉक्स क्यूएमएल नियंत्रण लागू किया गया)।


जूलियन के उत्तर के आगे - इसे प्राप्त करने का एक आसान तरीका QQuickWidget का उपयोग QML दृश्य को प्रदर्शित करने के लिए करना है, और उसके बाद QQuickWidget के बच्चे के रूप में एक नियमित QWidget जोड़ें। आप दृश्य में किसी आइटम को QWidget एंकर करने के लिए एक साधारण इंटरमीडिएट QObject भी जोड़ सकते हैं।

उदाहरण के लिए:

Main.qml में:

Item {

    ... // layouts, extra items, what have you

        Item
        {
            objectName: "layoutItem"
            anchors.fill: parent
        }

    ... // more layouts, extra items, etc.
}

widgetanchor.h:

class WidgetAnchor: public QObject
{
    ptr<QWidget> _pWidget;
    QPointer<QQuickItem> _pQuickItem;
public:
    WidgetAnchor(QWidget* pWidget, QQuickItem* pItem)
        : QObject(pWidget), _pWidget(pWidget), _pQuickItem(pItem)
    {
        connect(_pQuickItem, &QQuickItem::xChanged, this, &WidgetAnchor::updateGeometry);
        connect(_pQuickItem, &QQuickItem::yChanged, this, &WidgetAnchor::updateGeometry);
        connect(_pQuickItem, &QQuickItem::widthChanged, this, &WidgetAnchor::updateGeometry);
        connect(_pQuickItem, &QQuickItem::heightChanged, this, &WidgetAnchor::updateGeometry);
        updateGeometry();
    }
private:
    void updateGeometry()
    {
        if (_pQuickItem)
        {
            QRectF r = _pQuickItem->mapRectToItem(0, QRectF(_pQuickItem->x(), _pQuickItem->y(), _pQuickItem->width(), _pQuickItem->height()));
            _pWidget->setGeometry(r.toRect());
        }
    }
};

Main.cpp में:

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    auto pqw = new QQuickWidget;
    pqw->setSource(QUrl::fromLocalFile("main.qml"));
    pqw->setResizeMode(QQuickWidget::SizeRootObjectToView);
    pqw->setAttribute(Qt::WA_DeleteOnClose);
    auto pOwt = new MyWidget(pqw);
    if (auto pOverlayItem = pqw->rootObject()->findChild<QQuickItem*>("overlayItem"))
        new WidgetAnchor(pOwt, pOverlayItem);
    pqw->show();

    return app.exec();
}

प्रलेखन में कहा गया है कि QQuickWidget का उपयोग QQuickView और QWidget :: createWindowContainer पर फायदे हैं, जैसे कि स्टैकिंग ऑर्डर पर कोई प्रतिबंध नहीं है, लेकिन इसमें 'मामूली प्रदर्शन हिट' है।

उम्मीद है की वो मदद करदे।


आप QQuickPaintedItem क्लास का उपयोग कर QWidget को QML में एम्बेड कर सकते हैं: http://doc.qt.io/qt-5/qquickpainteditem.html

क्यूटी 5 का एक उदाहरण है: http://doc.qt.io/qt-5/qtquick-customitems-painteditem-example.html

आपको निजी विजेट विशेषता के साथ QQuickPaintedItem का अंतर्निहित कार्यान्वित करना चाहिए, जिसे आप एम्बेड करना चाहते हैं। पेंट विधि प्रदान करें, जो सिर्फ QtWidget प्रस्तुत करें और QTWidget एम्बेड करने के लिए QQuickPaintedItem के उत्तराधिकारी से प्रेषित माउस और अन्य ईवेंट प्रदान करें।

क्यूएसजी (क्यूटी दृश्य ग्राफ एपीआई) भी है, लेकिन उस चीज़ के साथ मेरा अनुभव चिकना नहीं था। मुझे विश्वास है कि मल्टीथ्रेडिंग में सुराग (विभिन्न धागे में प्रतिपादन करना (क्यूटी जीयूआई थ्रेड नहीं, हालांकि विंडोज़ पर यह सच नहीं है और सभी मुख्य जीयूआई थ्रेड में किए जाते हैं)।

मैंने QCustomPlot के एम्बेडिंग को कार्यान्वित किया है, यहां लिंक है: github.com/mosolovsa/qmlplot