ProgressSpin in PyQt (QML) aber wie?

Python und das Qt-Toolkit, erstellen von GUIs mittels des Qt-Designers.
Antworten
AngelusNoctis
User
Beiträge: 92
Registriert: Sonntag 16. Dezember 2007, 20:03

Hi

Hab ne frage und hoffe das mir jemand helfen kann (Hallo Lunar) XD

Also ich hätte gerne sowas hier:
http://www.webappers.com/img/2011/08/sp ... ss-bar.png

In meinem Dialog und da gibts ja zwei Möglichkeiten

a) QML
b) GIF mit QMovie

QMovie wäre kein Problem, aber ich würde das gerne in QML realisieren, die frage ist nur: "Wie zum Teufel nutze ich QML richtig?"

Das Beispiel von http://www.riverbankcomputing.co.uk/sta ... l/qml.html funktioneirt bei mir nicht.

Also kennt jemand gute Tutorials zum Thema PyQt + QML oder kann mir ne Beispiel-Implementierung dieses ProgressSpins zeigen QML und Py File? :)
lunar

@AngelusNoctis Was funktioniert nicht? Ist es wirklich so schwer, Fehler zu beschreiben? :roll:
AngelusNoctis
User
Beiträge: 92
Registriert: Sonntag 16. Dezember 2007, 20:03

So, noch ne Frage.

Also ich versuch jetzt den BusyIndicator/Spinner/Whatever aus dem Beispiel: http://qt-project.org/wiki/QML_Progress_Spinner an zu zeigen.

Hab einfach kurz mal "rumprobiert", aber mit dem Ergebnis das nur ein Fenster aufgeht ohne Inhalt.

Liegt das jetzt am Python Code oder stimmt die QML nicht?

Und ja, ich hab keine Ahnung von QML und finde irgendwie keine tollen Tutorials :(

Code: Alles auswählen

from PyQt4 import QtCore, QtGui, QtDeclarative


class main(QtCore.QObject):
    def __init__(self):
        QtGui.QWidget.__init__(self)

if __name__ == '__main__':

    import sys

    app = QtGui.QApplication(sys.argv)

    main = main()

    view = QtDeclarative.QDeclarativeView()
    view.setSource(QtCore.QUrl.fromLocalFile('./test.qml'))
    view.setResizeMode(QtDeclarative.QDeclarativeView.SizeRootObjectToView)


    view.setGeometry(QtCore.QRect(100, 100, 450, 450))
    view.show()

    sys.exit(app.exec_())

Und die test.qml wäre:

Code: Alles auswählen

    import QtQuick 1.0
    import ZapBsComponents 1.0
     
    Item {
        id: progressSpinner
        property alias minimum: progress.minimum
        property alias maximum: progress.maximum
        property alias value: progress.value
        property alias progressWidth: progress.width
        property alias progressHeight: progress.height
        property color color: "#77B753"
     
        BusyIndicator {
            id: busyIndicator
            anchors.fill: parent
            foregroundColor: progressSpinner.color
            opacity: ( value == maximum ) ? 0.0 : 1.0
            Behavior on opacity {
                NumberAnimation {
                    duration: 100
                }
            }
     
            RotationAnimation
            {
                target: busyIndicator
                property: "rotation" // Suppress a warning
                from: 0
                to: 360
                direction: RotationAnimation.Clockwise
                duration: 1000
                loops: Animation.Infinite
                running: progress.value < progress.maximum
            }
        }
     
lunar

Liegt die QML-Datei in dem Verzeichnis, aus dem Du das Programm startest?

Versuche besser:

Code: Alles auswählen

script_directory = os.path.abspath(os.path.dirname(__file__))
qml_source = os.path.join(script_directory, 'test.qml')
view.setSource(QUrl.fromLocalFile(qml_source))
Platziere die QML-Datei dann im selben Verzeichnis, in dem auch die Python-Datei liegt.

Entferne die überflüssige "main"-Klasse. Du hast Glück, dass Dein Programm ihretwegen nicht einfach abstürzt, denn Du rufst dort den Konstruktor von QWidget auf, obwohl die Klasse nur von QObject ableitet.

Höre auf zu raten, sondern lese die Dokumentation, und dann denke nach, wie Du das mit anderen QML-Programmen kombinieren kannst.
AngelusNoctis
User
Beiträge: 92
Registriert: Sonntag 16. Dezember 2007, 20:03

Hi

Erst mal danke

Beide Dateien lagen im selben Ordner, aber wie ich gesehen habe spuckt der QMLViewer sogar ne Fehlermeldung raus und zwar dass das Modul "ZapBsComponents" gar nicht existiert.

Das Beispiel ist mir bekannt, hatte ich auch selbst verlinkt.
Aber an Doku fehlt es definitiv und die Beispiele wie Minehunt find ich zu komplex für nen Einstieg.

Ich guck mir jetzt mal http://doc.qt.digia.com/qt/qdeclarativeexamples.html an und versuch rauszufinden wieso mir angeblich ZapBsComponents fehlt

So wie ich jetzt gesehen habe bräuchte ich für den Spinner sowieso nur qmlviewer und gut ist :)
lunar

Siehe http://qt-project.org/wiki/Busy-Indicator-for-QML

Es gibt keinen fertigen BusyIndicator, Du musst ihn selbst implementieren und anschließend für QML registrieren. Im Beispiel wurde dazu der Name ZapBsComponents genutzt. Google hilft…

QtQuick und QML sind umfangreich dokumentiert, doch ich habe das Gefühl, dass Du an Doku gar nicht interessiert bist, sondern an irgendwelchen Beispielen, an denen Du dann solange herumraten kannst, bis das Gewünschte herauskommt.
EmaNymton
User
Beiträge: 174
Registriert: Sonntag 30. Mai 2010, 14:07

Lunar hat Recht, die Dokumentation zu lesen kann nie schaden. Trotzdem habe ich dir mal ein kleines Beispiel gebastelt, weil ein Spinner/BusyIndicator ja eigentlich nur ein drehendes Bild darstellt.

Den Code kannst du mit dem qmlviewer einfach testen. Das Bild busy.png muss natürlich im gleichen Ordner liegen.
Beim Klick auf die MouseArea, also das gesamte Fenster startet bzw. stoppt der Spinner. Ich hoffe das hilft dir für den Anfang weiter, alles weitere musst du dann selbst dazu basteln ;)

main.qml

Code: Alles auswählen

import QtQuick 1.0
 
Rectangle {
    id: root
    width: 120
    height: 120

    BusyIndicator {
        id: busyIndicator
        anchors.fill: parent
    }

    MouseArea {
        anchors.fill: parent
        onClicked: {busyIndicator.visible ? 
                    busyIndicator.visible = false :  
                    busyIndicator.visible = true}
    }
}
BusyIndicator.qml

Code: Alles auswählen

import QtQuick 1.0

Image {
     id: container
     property bool on: false

     source: "busy.png"; 
     visible: container.on

     NumberAnimation on rotation {
         running: container.visible; from: 0; to: 360; loops: Animation.Infinite; duration: 1200
    }
}
AngelusNoctis
User
Beiträge: 92
Registriert: Sonntag 16. Dezember 2007, 20:03

Cool, danke an beide :)

Hab, momentan ne den QProgressIndicator vom Pradus Projekt übernommen, aber QML guck ich mir an...
AlphaX2
User
Beiträge: 53
Registriert: Dienstag 28. Juni 2011, 10:42

Hi,

man muss sich die Import-Anweisungen in QML wie jene aus Python vorstellen. Das heißt also, dass die "ZapBsComponents" sowas wie eine Bibliothek ist, in QML - fertige "Components". QML ist relativ einfach zu lernen und zu verstehen und bietet echt viele Möglichkeiten. Componenten sind so z.B. einfach fertige/funktionale Elemente, z.B. ein Button. Dafür würde man ein QML File erstellen, dass den Namen "Button.qml" trägt und darin den Button in QML schreiben. Also im einfachsten Fall ein Rectangle, Text und MouseArea. Dann kann man diese Button.qml auch in anderen Projekten wieder verwenden. Das gleiche betrifft die Ladeanzeige.

Übrigens, wenn du die Ladeanzeige laufen lassen willst während deine Python-Logik irgendwas erledigt, muss du das als QThread implementieren, der mit QML kommunizieren kann und beim Start des Threads muss QML gesagt bekommen, dass es den Spinner starten soll, am Ende des Threads stoppen.

EDIT: Ein QML Tutorial, welches die Grundlagen erklärt findest du bei meetmeego.org!

EDIT II: Da ich es selber grade hatte, man kann es statt einem Thread auch mit einem Property machen, dessen notify an ein Signal gebunden ist. ;) Nette Tutorials allgmein zu PySide/QML bzw. dazu wie man sowas mit Propertys implementieren kann gibts von Thomas Perl mit gPodder als Beispiel.

AlphaX2
Antworten