Dicas de PyQt4

Esse post irá apresentar alguns processos de desenvolvimento utilizando PyQt através da construção de um aplicativo simples e sua evolução. Algumas dicas como utilizar o designer para fazer as telas e layouts e integrá-lo no seu código-fonte, o casamento com expressões regulares, sinais, widgets gráficos (lineEdits, labels, comboBox, etc), arquivos, processos, strings…

qt.gif

Todo programa começa com uma idéia, certo? A idéia que eu tive para esse exemplo foi a utilização das variáveis globais no Linux e em especial a distribuição Gentoo, que utilizo no meu desktop. Procurando na documentação encontrei a informação necessária, da qual eu traduzi a definição:

O que é uma variável de ambiente?

Um variável de ambiente contém informações usadas por uma ou mais aplicações. Muitos usuários (e especialmente aqueles novos no Linux) tem dificuldade em na sua configuração e utilização. Contudo, aprender a usar os conceitos básicos das variáveis de ambiente pode facilitar a vida em muitos casos, principalmente na mudança de configurações de programas.

Primeira idéia:

Fazer um programa para ver as variáveis de ambiente citadas

O tutorial cita as seguintes variáveis globais: PATH, ROOTPATH, LDPATH, MANPATH, INFODIR, PAGER, KDEDIRS, CONFIG_PROTECT, CONFIG_PROTECT_MASK, EDITOR. A idéia foi fazer um programa gráfico para facilitar ao usuário iniciante entender o que significa as variáveis no seu sistema. Então o programa, inicialmente deverá:

1. Mostrar as variáveis globais mais utilizadas

2. Apresentar o significado de cada variável quando o usuário passasse o cursor do mouse em cima da palavra.

 

Para facilitar a vida, todos as telas serão feitas no Qt Designer, pois é mais fácil criá-las e arrumar o layout. A receita é bem simples, vamos imaginar que seu arquivo (widget, dialog, etc) no designer chame form.ui. Utilizaremos o utilitário pyuic4 para convertê-lo em código Python.

#> pyuic4 form.ui -o ui_form.py

O começo do arquivo ficará semelhante a este:


# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'form.ui'
#
# Created: Sun Feb 8 15:35:23 2008
#      by: PyQt4 UI code generator 4.3.1
#
# WARNING! All changes made in this file will be lost!

from PyQt4 import QtCore, QtGui

class Ui_Tela(object):
def setupUi(self, Tela):
Tela.setObjectName("Tela")

Depois, no código-fonte, iremos importar (ou herdar) a classe Ui_Tela onde Tela é um nome qualquer que eu escolhi. Nos outros exemplos chamarei o widget de form, logo a classe será Ui_Form.


import sys, re, os, string
from PyQt4 import QtCore, QtGui
from ui_form import Ui_Tela

class QEnvApp(QtGui.QDialog,Ui_Tela):
def __init__(self):
QtGui.QDialog.__init__(self)
self.setupUi(self)

# O CÓDIGO-FONTE AQUI

if __name__ == '__main__':

app = QtGui.QApplication(sys.argv)
dialog = QEnvApp()
dialog.show()
sys.exit(app.exec_())

Podemos pensar a primeira maneira de fazer isso com comandos já conhecidos do bash como: echo $NOME_DA_VARIÁVEL


def getEnv(self):

self.pathEdit.setText((os.popen("echo $PATH")).readline())
self.rootpathEdit.setText((os.popen("echo $ROOTPATH")).readline())
self.ldpathEdit.setText((os.popen("echo $LD_PATH")).readline())

Ou então, fazer de uma maneira mais portável:


def getEnv(self):

self.pathEdit.setText(os.environ['PATH'])
self.rootpathEdit.setText(os.environ['ROOTPATH'])
self.ldpathEdit.setText(os.environ['LD_PATH'])

Segunda Idéia

Mostrar TODAS as variáveis do sistema

Da primeira idéia surgiram dois incovenientes, primeiro que o texto contido nas variáveis excedia o tamanho da área reservada, e segundo que não mostrava TODAS as variáveis de ambiente setadas. Como são muitas variáveis, achei melhor organizá-las em uma comboBox e utilizar uma caixa de texto.

Dois detalhes são interessantes, a primeira é referente a maneira de filtrar o nome das variáveis, abaixo a função que pega a saída do comando export e através do filtro de uma expressão regular obtém os nomes das variáveis:


def getEnvNames(self):
p = os.popen("export")
while 1:
line = QtCore.QString(p.readline())
if not line: break
sline = line.split(QtCore.QRegExp("[^A-Z_]+"))
self.comboBox.insertItem(0,sline[1])

Também podemos escrever o código acima de uma maneira mais elegante, tornado-o mais portável, suponha que você rode seu script no Windows:


def getEnvNames(self):
for param in os.environ.keys():
self.comboBox.insertItem(0,param)

O outro detalhe, para evitar erros como “TypeError: popen() argument 1 must be string, not QString” é necessário fazer uma conversão do tipo QString para o tipo string. Escolhi converter utilizando o codec unicode_escape pois transforma a string em um formato compatível com o código-fonte, entretanto há uma lista de codecs disponíveis.


def showEnv(self, _index):

var =  unicode(self.comboBox.currentText(), 'unicode_escape')
p = os.popen( "echo $" + var )
self.textEdit.setText(p.readline())

Terceira Idéia

Um pouco de interação…

Até o momento o programa não dá possibilidade ao usuário de alterar e gravar o conteúdo de alguma variável, iremos fazer isso:

Lembrando de estabelecer as conexões dos widgets:

def makeconnections(self):
self.connect(self.comboBox, QtCore.SIGNAL('activated(int)'), self.showEnv)
self.connect(self.salvarButton, QtCore.SIGNAL('clicked()'), self.salvar )
self.connect(self.salvarpermanenteButton, QtCore.SIGNAL('clicked()'), self.salvarPermanentemente )

O botão Salvar grava o conteúdo na variável no ambiente de execução do programa, portanto se você fechar o programa e ver o estado da variável verá que nada foi alterado. Para ver o resultado, descomente, na função salvar do script as seguintes linhas:


#for param in os.environ.keys():
#print "%20s %s" % (param,os.environ[param])

Já o botão Salvar Permanentemente grava o conteúdo no arquivo ~/.bashrc, para que todas as novas instâncias mantenham o conteúdo alterado. Será salvo no final do arquivo.


def salvarPermanentemente(self):

path = os.environ['HOME'] + "/.bashrc"

var = unicode(self.comboBox.currentText(), 'unicode_escape')

value = unicode(self.textEdit.toPlainText(), 'unicode_escape')

f=file(path, 'a')
f.write("export " + var + "=" + value )
f.close()

Os três exemplos estão no arquivo abaixo

*** Download (tar.gz) ***

Conclusão

Acredito que um principais objetivos das linguagens interpretadas é proporcionar a construção de aplicativos de forma mais rápida se comparado com outras linguagens como Java ou C++. Pode-se desenvolver desde pequenos utilitários até automatizar grandes processos: como backup, configuração, comunicação, interfaces, front-ends; tudo aliado a vantagem da independência em relação ao Sistema Operacional (exceto em casos específicos, como editar o arquivo .bashrc). Alguns exemplos de projetos, como o PyQemu – uma interface em Python para o Qemu – refletem as possibilidades da linguagem e sua utilização nos mais diversos segmentos.

Referências:

http://docs.python.org/lib/lib.html

http://wiki.python.org/moin/PyQt4

http://www.diotavelli.net/PyQtWiki

Uma resposta

  1. Grande Maluta…
    Cara tenho acompanhado seus posts e digo que o blog tá bem legal… em especial, este ultimo post e o de UML em C são bem interessantes… Faltou umas referências bibliográficas e a indicação de algumas ferramentas lá no artigo do cara, mas nada que o google não possa providenciar =-)

    Fiquei de comentar o segundo post sobre retorno de referências a variaveis locais, mas o tempo curto me impede um pouco…assim que sobrar um tempinho eu faço isso…

    No mais é isso!

    Att

Deixe uma resposta

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s

%d blogueiros gostam disto: