Olá programadores e programadoras! Tudo bem com vocês? Espero que sim! No capítulo de hoje criaremos o nosso primeiro App com Python e PySide2!
Antes de começarmos a escrever o código para o nosso App, devemos instalar a biblioteca PySide2 em nosso computador. Para isso, utilize o seguinte comando:
pip install PySide2
Com a biblioteca devidamente instalada, podemos começar a nossa aula.
Vamos criar nosso primeiro aplicativo! Para começar, crie um novo arquivo Python, você pode chamá-lo como quiser (por exemplo, meu_app.py) e salvá-lo em algum lugar acessível. Escreveremos nosso aplicativo simples neste arquivo.
O código-fonte do seu primeiro aplicativo é mostrado abaixo. Digite-o literalmente e tome cuidado para não cometer erros. Se você errar, o Python informará o que há de errado:
# --- Importar as bibliotecas --- #
import sys # necessário apenas para acesso aos argumementos da linha de comando
from PySide2.QtWidgets import QApplication, QWidget
# --- Você precisa de uma (e apenas uma) instância de QApplication por aplicativo --- #
# --- Passe sys.argv para permitir argumentos de linha de comando para seu aplicativo --- #
# --- Se você sabe que não usará argumentos de linha de comando, QApplication([]) também funciona --- #
app = QApplication(sys.argv)
# --- Crie um widget Qt, que será a nossa janela --- #
janela = QWidget()
janela.show() # IMPORTANTE!!!!! As janelas ficam ocultas por padrão
# --- Iniciar o loop de eventos --- #
app.exec_()
Agora você verá sua janela. O Qt cria automaticamente uma janela com as decorações normais da janela e você pode arrastá-la e redimensioná-la como qualquer janela:
Figura 1: Janela do App.
O que você verá dependerá da plataforma em que você está executando este exemplo.
Vamos percorrer o código linha por linha para entendermos exatamente o que está acontecendo.
Primeiro, importamos as classes PySide2 necessárias para o aplicativo. Aqui estamos importando QApplication, o manipulador de aplicativos e QWidget, um widget GUI vazio básico, ambos do módulo QtWidgets:
from PySide2.QtWidgets import QApplication, QWidget
Os principais módulos do Qt são QtWidgets, QtGui e QtCore.
A seguir criamos uma instância de QApplication, passando sys.arg, que é uma lista Python contendo os argumentos da linha de comando passados para a aplicação:
app = QApplication(sys.argv)
Se você sabe que não usará argumentos de linha de comando para controlar o Qt, poderá passar uma lista vazia, por exemplo:
app = QApplication([])
A seguir, criamos uma instância de um QWidget usando janela como nome da variável:
janela = QWidget()
janela.show()
No Qt, todos os widgets de nível superior são janelas – ou seja, eles não têm um pai e não estão aninhados em outro widget ou layout. Isso significa que você pode criar tecnicamente uma janela usando qualquer widget que desejar.
Mas o que é uma janela?
Mantém a interface do usuário do seu aplicativo;
Cada aplicação precisa de pelo menos uma (…mas pode ter mais) e;
O aplicativo (por padrão) será encerrado quando a última janela for fechada.
Finalmente, chamamos app.exec_() para iniciar o loop de eventos.
Antes de exibir a janela na tela, existem alguns conceitos-chave a serem apresentados sobre como os aplicativos são organizados no mundo Qt. Se você já estiver familiarizado com loops de eventos, poderá pular com segurança para a próxima seção.
O núcleo de todos os aplicativos Qt é a classe QApplication. Cada aplicativo precisa de um — e apenas um — objeto QApplication para funcionar. Este objeto contém o loop de eventos do seu aplicativo – o loop principal que governa toda a interação do usuário com a GUI.
Cada interação com seu aplicativo — seja o pressionamento de uma tecla, o clique do mouse ou o movimento do mouse — gera um evento que é colocado na fila de eventos. No loop de eventos, a fila é verificada em cada iteração e se um evento em espera for encontrado, o evento e o controle são passados para o manipulador de eventos específico para o evento. O manipulador de eventos lida com o evento e depois passa o controle de volta ao loop de eventos para aguardar mais eventos. Há apenas um loop de eventos em execução por aplicativo.
A classe QApplication:
QApplication contém o loop de eventos Qt;
É necessária uma instância de QApplication;
Seu aplicativo fica esperando no loop de eventos até que uma ação seja executada e;
Existe apenas um loop de eventos a qualquer momento.
O sublinhado existe porque exec era uma palavra reservada no Python 2.7. PySide2 lida com isso anexando um sublinhado ao nome usado na biblioteca C++. Você também verá métodos .print_() em widgets, por exemplo.
Como descobrimos na última parte, no Qt qualquer widget pode ser janela. Por exemplo, se você substituir QtWidget por QPushButton. No exemplo abaixo, você obteria uma janela com um único botão:
from PySide2.QtWidgets import QPushButton
janela = QPushButton('Me aperte!')
janela.show()
Isso é legal, mas não é muito útil – é raro que você precise de uma interface do usuário (UI, em inglês, User Interface) que consista em apenas um único controle! Mas, como descobriremos mais tarde, a capacidade de aninhar widgets dentro de outros widgets usando layouts significa que você pode construir UIs complexas dentro de um QWidget vazio.
Mas, o Qt já tem uma solução para você — o QMainWindow. Este é um widget pré-fabricado que fornece muitos recursos de janela padrão que você usará em seus aplicativos, incluindo barras de ferramentas, menus, uma barra de status, widgets encaixáveis e muito mais. Veremos esses recursos avançados mais tarde, mas, por enquanto, adicionaremos um QMainWindow simples e vazio ao nosso aplicativo:
# --- Importar as bibliotecas --- #
import sys
from PySide2.QtWidgets import QApplication, QMainWindow
# --- Criar a instância do App -- #
app = QApplication(sys.argv)
# --- Criar a janela do App --- #
janela = QMainWindow()
janela.show()
# --- Iniciar o loop de eventos --- #
app.exec_()
Agora você verá sua janela principal. Parece exatamente igual a antes!
Portanto, nosso QMainWindow não é muito interessante no momento. Podemos consertar isso adicionando algum conteúdo. Se você deseja criar uma janela personalizada, a melhor abordagem é subclassificar QMainWindow e então incluir a configuração da janela no bloco __init__. Isso permite que o comportamento da janela seja independente. Podemos adicionar nossa própria subclasse de QMainWindow — chame-a de TelaPrincipal para manter as coisas simples:
# --- Criar uma classe que herda QMainWindow para personalizar a janela principal do seu aplicativo --- #
class TelaPrincipal(QMainWindow):
"""Classe que cria a tela principal do App."""
def __init__(self):
"""Função responsável por inicializara classe."""
# --- Herdar a classe QMainWindow --- #
super().__init__() # 1
# --- Colocar o nome da janela --- #
self.setWindowTitle('Meu App')
# --- Criar um botão --- #
botao = QPushButton('Me aperte!')
# --- Deixar o widget centralizado --- #
self.serCentralWidget(botao) # 2
# --- Criar a instância do App --- #
app = QApplication(sys.argv)
# --- Criar a janela do App --- #
janela = TelaPrincipal()
janela.show()
# --- Executar o loop de eventos --- #
app.exec_()
Devemos sempre chamar o método __init__ da classe super() e;
Use .setCentralWidget para colocar um widget no QMainWindow.
Em nosso bloco __init__ usamos primeiro .setWindowTitle() para alterar o título de nossa janela principal. Em seguida, adicionamos nosso primeiro widget — um QPushButton — no meio da janela. Este é um dos widgets básicos disponíveis no Qt. Ao criar o botão você pode passar o texto que deseja que o botão exiba.
Finalmente, chamamos .setCentralWidget() na janela. Esta é uma função específica do QMainWindow que permite que você defina o widget que vai no meio da janela.
Agora você verá sua janela novamente, mas desta vez com o widget QPushButton no meio. Pressionar o botão não fará nada, resolveremos isso a seguir:
Figura 2: Botão do App.
Com fome de widgets? Abordaremos mais widgets em detalhes em breve, mas se você estiver impaciente e quiser avançar, pode dar uma olhada na documentação do QWidget. Experimente adicionar diferentes widgets à sua janela!
A janela atualmente pode ser redimensionada livremente – se você pegar qualquer canto com o mouse, poderá arrastá-la e redimensioná-la para o tamanho que desejar. Embora seja bom permitir que os usuários redimensionem seus aplicativos, às vezes você pode querer impor restrições aos tamanhos mínimos ou máximos ou bloquear uma janela em um tamanho fixo.
No Qt, os tamanhos são definidos usando um objeto QSize. Aceita parâmetros de largura e altura nessa ordem. Por exemplo, o seguinte criará uma janela de tamanho fixo de 400x300 pixels. Importe o módulo QSize no começo do código e adiciona o seguinte código ao final da função __init__:
from PySide2.QtCore import QSize
class TelaPrincipal(QMainWindow):
def __init__(self):
.
.
.
self.setFixedSize(QSize(400, 300))
app = QApplication(sys.argv)
.
.
.
Você verá uma janela de tamanho fixo – tente redimensioná-la, não funcionará.
Assim como .setFixedSize() você também pode chamar .setMinimumSize() e .setMaximumSize() para definir os tamanhos mínimo e máximo respectivamente. Experimente você mesmo! Você pode usar esses métodos de tamanho em qualquer widget.
Neste capítulo cobrimos a classe QApplication, a classe QMainWindow, o loop de eventos e experimentamos adicionar um widget simples a uma janela. No próximo capítulo, daremos uma olhada nos mecanismos que o Qt fornece para que widgets e janelas se comuniquem entre si e com seu próprio código.