c++ क्यूटी/क्यूएमएल: सी++ से QML तक QImage भेजें और GUI पर QImage प्रदर्शित करें




qt (2)

मैंने एक कक्षा Publisher बनाया जो समय-समय पर एक QImage ऑब्जेक्ट को छोड़ देता है।

हालांकि मुझे QImage को QML तत्व में खींचने में कठिन समय हो रहा है। ऐसा प्रतीत होता है कि Image और Canvas QML घटकों को QImage बजाय एक QUrl आवश्यकता होती है, लेकिन मुझे यकीन नहीं है कि मेरे QImage को QUrl कैसे परिवर्तित करें। संपादित 4: जब मैं QUrl कहता हूं, मेरा मतलब यह नहीं है कि मैं एक छवि को एक यूआरएल में बदलने की कोशिश कर रहा हूं। यह बकवास है। मेरा मतलब है कि मैं इस छवि का संदर्भ उत्पन्न करना चाहता हूं, जो डिस्क पर नहीं है, और डेटा प्रकार जो QML घटक पूछ रहे हैं वह एक यूआरएल है।

मैंने कुछ शोध किया है और पाया है कि QQuickImageProvider एक समाधान प्रदान करता है, लेकिन मुझे कोई QQuickImageProvider नहीं मिला है कि मेरे QUrl सिग्नल को एक QUrl कैसे परिवर्तित किया QUrl जिसे मैं ड्राइंग के लिए उपयोग कर सकता हूं। किसी भी उदाहरण कोड या संदर्भ दस्तावेज की सराहना की जाएगी।

आपकी सहायताके लिए धन्यवाद!

Edit1:

मैंने यहां एक नज़र डाली है: http://qt-project.org/doc/qt-5.0/qtquick/qquickimageprovider.html और मुझे नहीं लगता कि मैं त्वरित छवि प्रदाता को QImage कैसे पास करता हूं और इससे एक QURL बना देता हूं ।

EDIT2। हेडर यहाँ है। कार्यान्वयन महत्वपूर्ण नहीं होना चाहिए।

class Publisher
{
    Q_OBJECT

public:
    Publisher(QObject* parent = 0);

    virtual ~Publisher(void);

Q_SIGNALS:

    void newImage(const QImage& newImage);
};

संपादित करें 3. मेरा क्यूएमएल कोड यहां है, लेकिन मुझे नहीं पता कि मेरे क्यूमेज को कैसे आकर्षित किया जाए, इसलिए यह कोड अर्थहीन है।

मेरी main.cpp फ़ाइल :

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

    qmlRegisterType<Publisher>("Components", 1, 0, "Publisher");

    QtQuick2ApplicationViewer viewer;
    viewer.setMainQmlFile(QStringLiteral("qml/QQuickViewExample/main.qml"));
    viewer.showExpanded();

    return app.exec();
}

मेरी main.qml फ़ाइल :

import QtQuick 2.0
import Components 1.0

Rectangle {
    id : testRect
    width: 360
    height: 360

    Image{
        anchors.fill: parent
        id: myImage

        Publisher {
            id: myPub

            onNewImage: {
                myImage.source = newImage;  #I know this doesnt work, it needs a QUrl and not a QImage
            }
        }
    }
}

जब मेरे पास छवि-उत्पादक सी ++ कक्षाएं थीं, जिन्हें मैं क्यूएमएल में एम्बेड करना चाहता था, मैंने हमेशा सी ++ वर्ग को QDeclarativeItem उप-वर्ग बनाकर किया है (पाठ्यक्रम का एक नया QtQuick 2.0 समकक्ष होगा), ओवरराइड करना उपयुक्त ड्राइंग कोड के साथ पेंट विधि, जो कि जितनी सरल हो सके

void MyItem::paint(QPainter* painter,const QStyleOptionGraphicsItem*,QWidget*) {
  painter->drawImage(QPointF(0.0f,0.0f),_image);
}

यदि आपके पास पहले से सही आकार का QImage है ... और जॉब हो गया। एनीमेशन के लिए, बस पिंग अपडेट () जब ड्रॉ करने के लिए कुछ नया है।


दूसरे शब्दों में, आपके पास एक QImage ले जाने वाला सिग्नल उत्सर्जित करने वाला वर्ग है और उस छवि के साथ QML में किसी आइटम को अपडेट करना चाहते हैं? कई समाधान हैं, जिनमें से कोई भी "QImage को एक QUrl में परिवर्तित नहीं करना" शामिल है (जो भी इसका मतलब है, निश्चित रूप से आपको अपने छवि डेटा को ले जाने वाला data यूआरएल प्राप्त करने की आवश्यकता नहीं है ...)

एक छवि प्रदाता का प्रयोग करें

इसका मतलब है कि आप अपनी क्यूएमएल फाइलों में एक सादा Image वस्तु का उपयोग कर सकते हैं।

  1. एक QQuickImageProvider उप QQuickImageProvider बनाएँ; इसे एक QImage सदस्य (प्रदाता के लिए छवि) दें, requestImage को ओवरराइड करें छवि को उस छवि को प्रदान करने के लिए (वास्तविक id अनुरोधित नहीं है, नीचे देखें), और एक स्लॉट जो QImage प्राप्त करता है और सदस्य को अद्यतन करता है।
  2. अपने Publisher सिग्नल को अपने प्रदाता के स्लॉट से कनेक्ट करें
  3. QQmlEngine::addImageProvider माध्यम से प्रदाता को क्यूएमएल इंजन में स्थापित करें ( QQuickView::engine देखें); फिर id वास्तव में कोई फर्क नहीं पड़ता, बस एक समझदार एक का उपयोग करें
  4. क्यूएमएल में, इस तरह के स्रोत के साथ बस एक सादा Image तत्व का उपयोग करें

    Image {
        id: myImage
        source: "image://providerIdPassedToAddImageProvider/foobar"
    }
    

    foobar आपके प्रदाता को पारित किया जाएगा, लेकिन फिर, यह वास्तव में कोई फर्क नहीं पड़ता।

  5. हम लगभग वहां हैं, अब हमें केवल क्यूएमएल दुनिया में छवि अपडेट को धक्का देने का एक तरीका चाहिए (अन्यथा छवि कभी भी अपडेट नहीं होगी)। एक Connections तत्व और जेएस के साथ कुछ करने के लिए यहां अपना उत्तर देखें।

    ध्यान दें कि सामान्य रूप से आपको Publisher एक क्यूएमएल प्रकार बनाने की आवश्यकता नहीं है, आपको केवल सी ++ में एक उदाहरण बनाने की आवश्यकता है और QQmlContext::setContextProperty माध्यम से इसे QML दुनिया में बेनकाब करना होगा।

एक कस्टम क्यूटी त्वरित 2 आइटम का प्रयोग करें

QQuickPaintedItem शायद नौकरी के लिए सबसे सुविधाजनक है क्योंकि यह एक QPainter लेने वाली एक paint विधि प्रदान करता है। इसलिए बड़ी योजना है

  1. Subclass QQuickPaintedItem : उप QQuickPaintedItem QImage को चित्रित करने के लिए संग्रहीत करता है और एक स्लॉट है जो नया QImage सेट करता है। इसके paint कार्यान्वयन को QPainter::drawImage का उपयोग करके छवि को चित्रित करता है।
  2. QmlRegisterType के माध्यम से QML दुनिया के उप-वर्ग का पर्दाफाश करें (ताकि आप इसे QML में उपयोग कर सकें)
  3. नई छवि को आइटम के स्लॉट में ले जाने वाले सिग्नल को जोड़ने का एक तरीका बताएं।

    यह मुश्किल हिस्सा हो सकता है।

    सी ++ में कनेक्शन करने के लिए आपको यह पता लगाने का एक तरीका चाहिए कि आइटम बनाया गया है (और इसे पॉइंटर प्राप्त करें); आमतौर पर objectName संपत्ति को कुछ मान पर असाइन करने के माध्यम से, फिर रूट ऑब्जेक्ट पर findChild का उपयोग करके (जैसा कि QQuickView::rootObject() द्वारा लौटाया जाता है) आइटम को पॉइंटर प्राप्त करने के लिए करता है। फिर आप सामान्य रूप से connect उपयोग कर सकते हैं।

    या , क्यूएमएल दुनिया में उजागर प्रकाशक सी ++ ऑब्जेक्ट पर एक Connections तत्व के माध्यम से, ऊपर की तरह, क्यूएमएल में कनेक्शन कर सकता है:

    MyItem {
        id: myItem
    }        
    
    Connections {
        target: thePublisherObjectExposedFromC++
        onNewImage: myItem.setImage(image)
    }
    

    जब आप MyItem उदाहरण बनाते हैं तो इससे कोई फर्क नहीं पड़ता है; लेकिन मुझे 100% यकीन नहीं है कि यह काम करेगा क्योंकि मुझे यकीन नहीं है कि आप QMmage प्रकार QQ में संभाल सकते हैं।





qml