Anzeigen und aktualisieren Sie ein Bild in QML

Ich verstehe nicht, wie ein Bild anzeigen, die in QML mit QQuickPaintedItem Klasse (oder vielleicht eine andere Methode ?).

Mein Programm ist derzeit die Anzeige mit QImage und ein ImageProvider, es funktioniert aber zufällig abgestürzt, so würde ich mag, um zu versuchen eine andere Methode.

Außerdem sollte das Bild jedes mal aktualisiert, wenn ein neues Bild übertragen wird.

Bekomme ich die Informationen aus einer uchar raw-Daten, aber ich sehe nicht, wie die Farbe von raw-Daten.

Zudem eine neue raw-Daten kommen bei etwa 60 fps, so dass die QML aktualisieren müssen, das Bild ist zu diesem Preis.

EDIT :

Andere Teile des Codes :

Meiner Klasse ist :

class StreamPainter : public QQuickPaintedItem
{
    Q_OBJECT

public:
    StreamPainter(QQuickItem *p = 0):QQuickPaintedItem(p){}
    ~StreamPainter();

    void paint(QPainter *painter){painter->drawImage(QPoint(0, 0), _streamImage);}


public slots:
    void onImageAvailable(QImage image) {
        _streamImage = image;
        update();
private:
    QImage _streamImage;

};

In main :

für die ungültige Eigenschaft name, es war durch den import StreamPainter 1.0, scheint es nicht mag diesen Namen, da war es consfused, ich habe es geändert myModule und der Fehler verschwand.

qmlRegisterType<StreamPainter>("myModule", 1, 0, "StreamPainter");

Erstellung des Objekts und der thread :

streamImage = new StreamPainter();
myPipeThread = new PipeThread(streamImage);

Thread-Konstruktor :

PipeThread::PipeThread(StreamPainter* spvideostr)
:QThread(),
 _namedPipe(INVALID_HANDLE_VALUE),
 _spvideostr(spvideostr),
 _abort(false),
 _rawData(NULL)
{
    ...
}

Thread-Klasse, die ich Hinzugefügt habe :

signals:
    void imageAvailable(QImage image);

Dann in meinem thread, ich weiß das verbinden und in die während ich das QImage und ein signal auszusenden :

connect(this, SIGNAL(imageAvailable(QImage)), _spvideostr, SLOT(onImageAvailable(QImage)));

while(...)
    QImage clImage(_rawData, IMG_WIDTH, IMG_HEIGHT,     QImage::Format_Indexed8);
    emit imageAvailable(clImage);

QML :

import QtQuick 2.0

import MyModule 1.0

StreamPainter {

    width : 100 
    height : 100 
InformationsquelleAutor Dinendal | 2016-04-20



2 Replies
  1. 0

    Ist es sehr einfach, alle Sie tun müssen ist, ziehen Sie das Bild in der paint() Methode:

    void paint(QPainter *painter) {
        painter->drawImage(QPoint(0, 0), yourImage);
    }

    Dann rufen Sie update() jedes mal yourImage änderungen.

    Ziehen keine raw-Daten, erstellen Sie eine QImage aus es mit dem richtigen format und zeichnen. Sie können die statische Methode QImage fromData(const uchar *data, int size, const char *format = Q_NULLPTR). Da QImage ist ein implizit freigegebene Objekt, können Sie effektiv yourImage = QImage::fromData(...) und dann update() jedes mal, wenn Sie neue Daten.

    EDIT:

    Sollten Sie erstellen das Objekt in QML. Auch, zu sehen, wie Sie threads verwenden, beachten Sie UI-Elemente, die nur zugegriffen werden kann, aus dem Haupt-thread. Dies bedeutet, dass Sie können nicht dies tun:

    _spvideostr->setStreamImage(clImage);
    _spvideostr->update();

    als Sie auf ein UI-Objekt aus einem anderen thread. Stattdessen sollten Sie eine signal-und slot-mit einer Verbindung in der Warteschlange, das Bild durch diese Verbindung, und legen Sie das Bild und rufen Sie update() vom Steckplatz des StreamPainter.

    Brauchen Sie nicht, dass:

    Q_PROPERTY(QImage streamImage READ streamImage WRITE setStreamImage NOTIFY streamImageChanged)

    Dieses Bild wird nur zugegriffen werden, die von dieser Klasse. So brauchen Sie nicht diejenigen, die entweder:

    QImage streamImage();
    void setStreamImage(QImage clImage);
    
    signals:
        void streamImageChanged(QImage Image);

    Was Sie brauchen es ist ein:

    public slots:
        void onImageAvaiable(QImage image) { ...set image and call update }

    In PipeThread Sie brauchen ein signal void imageAvaiable(QImage) verbinden imageAvaiable zu onImageAvaiable und emittieren das Bild:

    QImage clImage(_rawData, IMG_WIDTH, IMG_HEIGHT, QImage::Format_Indexed8);
    emit imageAvaiable(clImage);
    • Danke, ich werde versuchen, dass. Aber auf der QML Teil wie kann ich ihn anzeigen ? Muss ich update gibt oder Rendertarget ?
    • Erstellen Sie einfach eine Instanz des Objekts. Werfen Sie einen Blick auf diese Antwort, es ist ein wenig komplizierter als dein problem, aber es deckt alles, was Sie brauchen : stackoverflow.com/questions/35460369/…
    • Ihre aktuelle Element hat eine Größe von 0x0… geben Sie es einige Breite und Höhe.
    • Ja, ich habe eine ungültige Eigenschaft name. Muss ich zu erklären, Q_Property für jeden von Ihnen ?
    • Sind Sie Erben QQuickPaintedItem? Es erklärt die Eigenschaften.
    • Ich habe editiert den ersten post mit der Klasse, der registertype in Haupt-und Erstellung von Objekt-und thread.
    • Vielen Dank, ich werde es versuchen. @ddriver, die ich Hinzugefügt habe für onImageAvailable : _streamImage = image; this->update(); Und die Verbindung ist : connect(_spvideostr, SIGNAL(imageAvailable(QImage)), _spvideostr, SLOT(onImageAvailable(QImage))); ich bin mir nicht sicher, ob hier zu tun haben, ich einen link mit qml habe ich immer noch schwarze Fenster
    • Nein, ich habe geschrieben In PipeThread you need a signal void imageAvaiable(QImage) achten 😉 Auch müssen Sie nicht die this im this->update(). Die Verbindung wird erkennen, dass die beiden Objekte in verschiedenen threads und verwenden Qt::QueuedConnection, zwar können Sie es manuell als auch der Letzte parameter in der connec()
    • Ah ok, sorry. Ich habe das signal in der PipeThread Klasse und hat die connect : connect(this, SIGNAL(imageAvailable(QImage)), _spvideostr, SLOT(onImageAvailable(QImage))); QML ist : StreamPainter { width : 800 height : 800 aber noch habe ich keine Bilder
    • OK, ein paar andere Hinweise – 1 nicht Unterklasse QThread erstellen Sie stattdessen eine QObject basiert Arbeiter und verschieben Sie es an eine neue QThread, 2 – haben Sie die Verbindung von der Haupt-thread, 3 – stellen debug-Anweisungen im code um zu sehen, wo Sie sind und was ausgeführt wird und was nicht.
    • Ich habe versucht, die Anzeige bei manchen Farben funktioniert es, aber ich kann nicht aktualisieren. Es zeigt nur die Farbe, die Sie am initialilization der Klasse
    • Wie ich schon sagte, versuchen, die Verbindung von der Haupt-thread. Beim erstellen der Maler und das Gewinde verfügt, schließen Sie diese sofort nach, dass.

  2. 0

    In meinem Fall habe ich aktualisieren, ein Bild in QML mit einer Funktion innerhalb der Komponente wie folgt:

    Image {
                    id: imageLogo
                    cache: false
                    anchors.fill: parent
                    //anchors.leftMargin: 20
                    Layout.preferredWidth: Math.round(parent.width / 1.5)
                    Layout.preferredHeight: Math.round(parent.height * 2)
    
                    function reloadImage() {
                        var oldSource = source
                        source = ""
                        source = oldSource
                    }//function to refresh the source
    
                }

    Ist und ich dann nur diese Funktion aufrufen, wo immer Sie wollen, laden Sie das Bild

    imageLogo.reloadImage()

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.