PyQt6 na oficina: de formulários técnicos ao .exe com PyInstaller e PDF

Engenharia de máquina e oficina não pedem “mais um dashboard web” no primeiro dia. Pedem um programa de mesa que o projetista ou o técnico abre, preenche dados de esteira/separador, calcula, gera PDF e — se possível — entrega como .exe no PC Windows da sala técnica sem instalar Miniconda. O repositório pyqt6_book (rótulo Tec_do_Brasil no README) é exatamente esse caderno: lições progressivas de PyQt6, a pasta tec_system com versões evolutivas de uma ferramenta de configuração, estudo auxiliar em micrograd, e notas explícitas de PyInstaller + fpdf.

Ângulo deste artigo: desktop para engenharia/oficina e a realidade de empacotar executável — não tutorial genérico de Qt Designer, e sem prometer métrica de “quantos segundos para gerar o PDF”. O que o repo ensina é método: UI que fala a língua da OF, relatório local, e empacotamento tratado como disciplina.

Mapa do repositório (o que existe de verdade)

Três blocos principais:

  1. pyqt6_book/ — séries pyqt6_book_1pyqt6_book_14, pyqt6_book_base, base_window: exercícios de janela, botões, ícones, layouts.
  2. tec_system/ — aplicação de domínio (cadastro/cliente, configuração de máquina, velocidade e carga no eixo, ação “Gerar PDF”), com histórico de versões (tec_system_0.1_.py0.6.0.0.py e o tec_system.py atual).
  3. micrograd/ — notebooks (demo.ipynb, trace_graph.ipynb) e artefatos de grafo; estudo de autograd ao lado da UI, não acoplado ao formulário de esteira.

O README fixa ambiente de estudo: Python 3.10.7, pip install pyqt6, pip install fpdf, e um bloco dedicado a compilar o bootloader do PyInstaller 5.4.1 com w64devkit (GCC) via waf, depois setup.py install. Isso já diz o tom: empacotar não é “um clique”.

Quem clona o repo só para “ver a tela bonita” e ignora as notas de bootloader vai repetir a falha clássica: funciona no interpretador do desenvolvedor e falha no .exe do cliente. O caderno é honestamente dual — widgets e empacotamento.

Por que PyQt6 para ferramenta técnica

Nas lições base (pyqt6_book_base, pyqt6_book_1), o padrão é QWidget/QMainWindow, QPushButton, QLabel, QMessageBox, ícones e atalhos. Isso mapeia bem para software de engenharia:

  • menus (Arquivo, Calcular, sobre) e barra de ferramentas com ícones padrão do estilo Qt;
  • formulários com QComboBox, QLineEdit, QGridLayout e área com scroll;
  • confirmação de saída (QMessageBox.question) — hábito essencial quando o operador pode perder preenchimento de OF.

No tec_system.py atual, a janela principal se chama JanelaPrincipal(QMainWindow), título voltado a cadastro, geometria ampla, e menus que levam a Configuração de Máquina e velocidade e Carga no Eixo. Há campos de domínio: tipo de máquina, modelo de esteira, configuração, nome do cliente, número da OF. Isso é software de oficina — não demo de “hello world” disfarçado.

A barra de ferramentas expõe Novo, Gerar PDF e Sair. O botão de PDF está ligado a gerar_pdf; em versões intermediárias (0.3_, 0.4_, 0.4.0.0_, 0.4.1.0_) a geração usa from fpdf import FPDF com página A4 em milímetros. Em versões mais enxutas o método pode estar stub — o histórico de arquivos mostra a evolução: primeiro a UI, depois o relatório.

Essa ordem (UI → relatório → empacote) é a ordem certa para ferramenta interna. Inverter — gerar .exe antes do PDF estável — só multiplica tempo de debug: você não sabe se o bug é Qt, fpdf, ou bootloader.

Layout, validação e o idioma da OF

Formulário de engenharia falha de formas chatas, não glamourosas:

  • campo numérico com vírgula onde o código espera ponto;
  • combo de modelo de esteira inconsistente com o tipo de máquina;
  • OF em branco gerando PDF “válido” sem identificação;
  • usuário fecha no X sem salvar e perde meia hora de preenchimento.

O que as lições PyQt6 treinam — QMessageBox, menus, widgets de entrada — é a base para atacar esses casos. O tec_system mostra a intenção de domínio; a robustez de validação é trabalho contínuo em cima das versões. Em oficina, validar antes de calcular e antes de gerar PDF vale mais do que tema escuro.

Práticas alinhadas ao espírito do repo (sem inventar features ausentes no código):

  • desabilitar “Gerar PDF” até campos mínimos preenchidos;
  • confirmar “Novo” se houver alteração não salva;
  • nomes de arquivo de PDF derivados de OF/cliente de forma previsível para a pasta do projeto;
  • manter o cálculo legível (funções com nome de domínio), não escondido em callback gigante de botão.

fpdf: o relatório que a oficina realmente usa

Na planta, o “entregável” do cálculo muitas vezes ainda é PDF na pasta da OF, não uma API. Por isso o README lista fpdf ao lado do PyQt6. O padrão observado nas versões que implementam funcao_gerar_pdf / gerar_pdf é:

  • instanciar FPDF('P', 'mm', 'A4');
  • escrever textos a partir dos widgets preenchidos;
  • salvar arquivo local.

Não é um motor tipográfico sofisticado. É o caminho curto entre formulário e papel digital que o comprador e o montador entendem. Para ferramenta interna, isso costuma ser suficiente — e evita puxar um stack web só para imprimir.

Cuidados práticos que aparecem assim que o PDF sai da máquina do autor:

  • fonte e encoding (caracteres do português);
  • caminho de salvamento com permissão de escrita no PC do cliente;
  • sobrescrita acidental de PDF anterior da mesma OF — decidir se versiona no nome ou confirma replace;
  • testar abertura no leitor de PDF padrão da sala técnica, não só no seu.

fpdf não precisa ser eterno. Se um dia o relatório crescer para template complexo, troca-se o motor. O ponto do estudo é amarrar UI → documento cedo, porque sem isso a ferramenta de configuração não fecha o ciclo da oficina.

A realidade do .exe: PyInstaller, bootloader e w64devkit

Empacotar PyQt6 no Windows é onde o otimismo morre. O README do repo documenta um caminho fonte do PyInstaller, não só pip install pyinstaller:

  1. usar pyinstaller-5.4.1;
  2. ter w64devkit-1.16.1 como compilador GCC;
  3. entrar na pasta bootloader e rodar python.exe ./waf distclean all (com opções de arch 64-bit);
  4. voltar à raiz do PyInstaller e python.exe setup.py install.

Por que isso aparece num caderno de UI? Porque em PCs de engenharia brasileiros (antivírus corporativo, políticas de execução, Python “da loja”, misturas de 32/64 bits) o bootloader pré-compilado do pip às vezes falha ou gera falso positivo. Recompilar o bootloader é o ritual de quem já quebrou a cara entregando .exe “onefile” que só abre na máquina do desenvolvedor.

Lições práticas alinhadas ao que o repo ensina:

  • fixe a versão do Python (aqui, 3.10.7) e do PyInstaller; “latest” quebra silenciosamente widgets Qt;
  • teste o .exe em máquina limpa sem o venv do desenvolvedor;
  • lembre que --onefile extrai para temp: antivírus e pastas redirecionadas atrapalham;
  • ícones e imagens (icone.png, fundos das lições) precisam ser declarados no spec/--add-data — o mesmo problema que o estudo Kivy enfrenta com .kv;
  • documente o comando exato de build no README da ferramenta, não só no chat do time.

Miniconda é marcado como “not needed”: a aposta é Python oficial + pip + disciplina de versões. Para oficina, menos gerenciador de ambiente é menos superfície de falha no PC do cliente. Se a TI já padronizou outro Python, adapte o pino de versão — o princípio permanece: uma versão conhecida, repetível.

onefile versus onedir na sala técnica

O repo enfatiza o caminho de bootloader; a escolha onefile/onedir é decisão de deploy:

  • onefile — um artefato fácil de copiar; custo de extração e mais atrito com antivírus;
  • onedir — pasta com DLLs visíveis; às vezes mais previsível em PC corporativo.

Não há número mágico aqui. Há teste de aceitação: abrir no PC alvo, gerar PDF, fechar, repetir após reboot. Se falhar, o log do PyInstaller e o Event Viewer contam mais que opinião de fórum.

tec_system como estudo de produto interno

Olhando o histórico de versões na pasta, vê-se o método de trabalho:

  • 0.10.3: consolidar janela, menus e primeiros cálculos/PDF;
  • 0.4.x: arquivos grandes (milhares de linhas) com formulário rico e FPDF;
  • 0.5.x / 0.6: experimentação de estrutura (incluindo exemplo de scroll em 0.6.0.0);
  • tec_system.py: linha atual com menus de máquina/eixo e hooks de PDF.

Isso é o oposto de framework mágico: versionar o próprio aplicativo enquanto a UI cresce. Para time pequeno de engenharia, guardar tec_system_0.4.1.0_.py ao lado do atual é rede de segurança quando um refactor de layout quebra o fluxo da OF.

O domínio (esteira, separador, título da máquina, OF) mostra a intenção: ferramenta de configuração/cálculo para quem vende ou monta máquina — desktop, local, com saída documental. Não é HMI de linha. É software de sala técnica adjacente ao chão: onde a receita nasce e o PDF viaja para a montagem.

Monólito de UI versus modularização

Arquivos grandes nas versões 0.4.x são sintoma conhecido: tudo na JanelaPrincipal. Funciona até o ponto em que um ajuste de layout de eixo quebra o PDF. A progressão natural — ainda como disciplina, não como feature inventada no repo — é separar:

  • widgets/páginas por domínio (máquina vs eixo);
  • funções de cálculo puras testáveis sem GUI;
  • camada de PDF que só recebe dados já validados.

O histórico de versões já é o seguro; modularizar é o próximo nível de higiene quando o formulário não cabe mais na cabeça de uma pessoa.

O que fazer com micrograd neste contexto

A pasta micrograd não alimenta o formulário de esteira. Ela existe como estudo paralelo de diferenciação automática e visualização de grafo. Num artigo de interfaces, o ponto útil é cultural: o mesmo repositório misturou UI de engenharia e estudo numérico. Isso é típico de quem vem de automação/eletrônica e não separa “software de painel” de “software de modelo”. O cuidado é não acoplar os dois sem necessidade: o .exe da oficina não precisa carregar notebook.

Se um dia um cálculo do tec_system exigir modelo mais rico, o estudo numérico ajuda o engenheiro — não o empacotador. Mantenha a fronteira: dependências do .exe de produção são PyQt6, fpdf e o que o formulário realmente importa.

Quando escolher PyQt6 em vez de GTK/C ou Kivy

  • PyQt6: formulários densos, menus, PDF, entrega Windows .exe, produtividade em Python.
  • GTK/C (c_gui_linux): painel leve em Linux com dependência de sistema, sem runtime Python.
  • Win32/C (c_gui_win): diálogo nativo mínimo e domínio total do toolchain.
  • Kivy: protótipo touch / canvas; outro contrato de layout (.kv) e de empacotamento.

Para a sala técnica que já vive em Windows e precisa de tela de parâmetros + PDF, PyQt6 no espírito do pyqt6_book é o encaixe natural — desde que o empacotamento seja tratado como disciplina, não como afterthought.

Há também o anti-padrão: começar em Kivy porque “é touch” e descobrir que o cliente quer grade de parâmetros, menu Arquivo e PDF. Aí você reescreve. O mapa da família de repos existe para escolher o contrato certo na primeira conversa de escopo.

HMI adjacente versus HMI de linha — de novo, com honestidade

tec_system pode ser aberto no mesmo PC que fala com CLP. Isso não o torna runtime de supervisão. Diferenças que importam na conversa com o cliente:

  • sem modelo de tags/alarmes do chão;
  • sem trilha de auditoria industrial completa;
  • sem requisito de safety na UI;
  • com foco em configuração/cálculo e documento.

Usar a palavra “HMI” para ferramenta de engenharia só com o qualificativo adjacente / de sala técnica evita expectativa errada. O artigo e o repo preferem precisão a marketing.

SOP mínimo de entrega do .exe na oficina

Antes de chamar a versão de “pronta para o PC da sala técnica”, feche um ritual curto:

  1. Build a partir de commit tagueado (não de working tree suja).
  2. Gerar o artefato com o comando documentado (spec ou linha PyInstaller).
  3. Copiar para um Windows sem Python instalado (VM ou notebook zerado).
  4. Abrir, preencher OF de teste, gerar PDF, abrir o PDF no leitor padrão.
  5. Fechar, reabrir, repetir uma vez — captura falha de path/temp no onefile.
  6. Anexar ao pacote: versão do app, Python 3.10.7, PyInstaller usado, e lista do que o programa não faz (não é IHM de linha, não grava CLP sozinho, etc.).

Esse SOP não aparece como script no repo; aparece como consequência das notas de bootloader. Quem ignora o passo da máquina limpa está só empacotando esperança.

Conclusão

pyqt6_book ensina duas coisas ao mesmo tempo: como construir interfaces que falam a língua da oficina (máquina, OF, cálculo, PDF) e como encarar o empacotamento Windows de frente (bootloader, w64devkit, versões pinadas). Ignore qualquer um dos lados e sobra demo de laboratório. Junte os dois e sobra caminho sério para ferramenta desktop de engenharia — rascunho evoluído em versões, sem fantasia de métrica e sem depender de stack web para o básico. O próximo passo depois do caderno não é “adicionar nuvem”; é fechar o ciclo OF → PDF → .exe testado em máquina limpa, com README que outro técnico da oficina consiga repetir.