Ir para o conteúdo

Python e Qt 6: Como utilizar um arquivo de interface QML com QQuickView()

Como utilizar um arquivo de interface QML com a linguagem de programação Python e QQuickView().

Código

Cuidado

Lembre-se de adequar a localização do arquivo de interface e ícones.

QML

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.0

ColumnLayout {
    anchors.fill: parent
    anchors.topMargin: 12
    anchors.bottomMargin: 12
    anchors.leftMargin: 12
    anchors.rightMargin: 12
    spacing: 12

    Label {
        id: label
        text: qsTr("Digite algo no campo de texto e clique no botão")
        textFormat: Text.RichText
        horizontalAlignment: Text.AlignHCenter
        verticalAlignment: Text.AlignVCenter
        wrapMode: Text.WordWrap
        Layout.fillHeight: true
        Layout.fillWidth: true
        Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
    }

    TextField {
        id: text_field
        Layout.fillWidth: true
        placeholderText: qsTr("Digite algo")
    }

    Button {
        id: button
        text: "Clique Aqui (ClassName)"
        Layout.fillWidth: true
        // Criando uma variável auxiliar:
        property var text_field_value: ""
        onClicked: {
            text_field_value = text_field.text
            if (text_field_value) {
                label.text = ClassName.on_button_clicked(text_field_value)
            }
            else {
                label.text = qsTr("Digite algo no campo de texto!")
            }
        }
    }

    Button {
        id: button_other
        text: "Clique Aqui (OtherClassName)"
        Layout.fillWidth: true
        // Criando uma variável auxiliar:
        property var text_field_value: ""
        onClicked: {
            text_field_value = text_field.text
            if (text_field_value) {
                label.text = OtherClassName.on_button_clicked(text_field_value)
            }
            else {
                label.text = qsTr("Digite algo no campo de texto!")
            }
        }
    }
}

Python

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# -*- coding: utf-8 -*-
"""Python e Qt 6: Interagir com arquivo de interface QML utilizando
QQuickView().
"""

from PySide6.QtCore import QUrl, QObject, Slot, QSize
from PySide6.QtGui import QGuiApplication, QIcon, QPixmap
from PySide6.QtQuick import QQuickView


class ClassName(QObject):
    """Métodos e funções criadas na classe podem ser acessadas no arquivo QML."""

    def __init__(self):
        super().__init__()

    # Primeiro valor vem do QML (deve ser definido um tipo).
    # Segundo valor é o retorno que será enviado para o QML
    # (deve ser atribuído um tipo).
    @Slot(str, result=str)
    def on_button_clicked(self, text):
        return f'Texto digitado: <b>{text}</b> (ClassName).'

    def closeEvent(self):
        """Método é executado quando a janela é fechada."""
        print('[!] A janela foi fechada [!]')


class OtherClassName(QObject):
    def __init__(self):
        super().__init__()

    @Slot(str, result=str)
    def on_button_clicked(self, text):
        return f'Texto digitado: <b>{text}</b> (OtherClassName).'


if __name__ == '__main__':
    import sys

    # Para exibir o ícone na taskbar (barra de tarefas) do windows.
    if sys.platform == "win32" or sys.platform == 'win64':
        from ctypes import windll

        appid = 'br.natorsc.exemplo'
        windll.shell32.SetCurrentProcessExplicitAppUserModelID(appid)

    application = QGuiApplication(sys.argv)

    # Informações da tela (monitor) principal.
    primary_screen = application.primaryScreen()
    primary_screen_geometry = primary_screen.geometry()
    primary_screen_height = primary_screen_geometry.height()
    primary_screen_width = primary_screen_geometry.width()

    # Dimensões da janela.
    window_width = int(primary_screen_width / 2)
    window_height = int(primary_screen_height / 2)

    # Atribuindo a classe a uma variável (obrigatório).
    class_name = ClassName()
    other_class_name = OtherClassName()

    # Configurando a janela.
    view = QQuickView()
    view.setTitle('Python e Qt 6: Signals e Slots (QML QQuickView)')
    view.setIcon(QIcon(QPixmap('../../../data/icons/icon.png')))
    view.setGeometry(0, 0, window_width, window_height)
    view.setMinimumSize(QSize(window_width, window_height))
    view.setMaximumSize(QSize(window_width + 200, window_height + 200))
    view.setResizeMode(QQuickView.SizeRootObjectToView)
    # Primeiro valor é o nome que será utilizado no arquivo QML.
    # Segundo valor uma instância da classe que contém os métodos e funções.
    view.rootContext().setContextProperty('ClassName', class_name)
    # Registrando outra classe para testar.
    view.rootContext().setContextProperty('OtherClassName', other_class_name)
    view.setSource(QUrl.fromLocalFile('ui/MainWindow.qml'))
    view.closeEvent = ClassName.closeEvent

    if view.status() == QQuickView.Error:
        sys.exit(-1)
    view.show()

    application.exec_()
    del view