quinta-feira, 21 de outubro de 2010

Exemplo de Classe em PyQt

Eu coloquei um exemplo anteriormente de código em PyQt e coloquei o link dos arquivos no 4shared, mas o link caiu e agora irei colocar mais um exemplo e vou comentar, e colocarei na tela mesmo.

#!/usr/bin/python
# -*- coding: utf-8 -*-
#importando as classes Qt abaixo
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from PyQt4 import QtCore
#importando a interface criada no QtDesigner e transformada em classe
#python através do comando pyuic
from interfaces import ui_formCadastroBensImoveis
import datas_Brasileiras
from PyQt4.QtSql import *

'''
nesse sistema, os objetos checkbox alteram o estado dos dicionários com 
chaves com nomes homônimos aos checkbox, dessa forma, a alteração
das chaves do dicionário é transparente e ele fica gravado 
no banco de dados
'''
class FormCadastroBensImoveis(QMainWindow, 
ui_formCadastroBensImoveis.Ui_cadastroBensImoveis, datas_Brasileiras.Datas_cpf):
    '''
    Classe de cadastro de bens imóveis
    tudo que iniciar com txt são caixas de texto 
    da classe principal da interface gráfica do programa, 
    o que for iniciado com cmb são os objetos
    combobox e com radio os radiobox, checkbox são checkbox etc
    '''
    def __init__(self, parent=None, bancodados='', usuario='0000'):
        super(FormCadastroBensImoveis, self).__init__(parent)
        self.setupUi(self)
        self.dic = {}
        self.promptComando = QSqlQuery()
        self.usuario = usuario
        self.populaComboIgreja()
        self.validarCamposNumericos()
        self.fazerConexoes(True)
        
    def fazerConexoes(self, novo=True):
        '''
        Essa função faz as conexões dos objetos
        com os sinais e eventos, função de salvar não está aqui
        porque quando eu usar esse mesmo módulo como alteração
        eu irei usar o botão com a função alterar.
        a biblioteca partial permite criar funções 
        sob demanda desse modo eu economizo muitas linhas
        de código, as funções que são parecidas
        são criadas automaticamente
        '''
        from functools import partial
        from cadastros import sair
        self.connect(self.txtDataConstrucao, SIGNAL('editingFinished()')
        , self.validarData)
        #A função findChildren retorna uma lista com 
        #todos os objetos que responderem 
        #a um tipo ou função específica.
        lista = self.findChildren(QCheckBox)
        for objeto in lista:
            self.connect(objeto, SIGNAL('stateChanged(int)'),
            self.alt_diversos)
            self.dic[unicode(objeto.objectName(), 'utf-8')] = u"não"
        self.connect(self.txtDataConstrucao, SIGNAL("editingFinished ()"),
        self.validarData)
        if novo:
            self.connect(self.btnSalvar, SIGNAL('clicked()'),
            self.salvarDados)
        
    def validarCamposNumericos(self):
        '''Essa função valida os campos numéricos usando o objeto 
        QDoubleValidator, ele é muito bom e eficiente,
        tem muitas vantagens sobre a máscara, novamente,
        eu uso um laço for aqui para deixar a função
        mais compacta e pythoniana :)
        '''
        validarReal = QDoubleValidator(0, 99999, 0, self)
        validarReal.setDecimals(2)
        listaObj = [self.txtAreaAverbadaCasaOracao,
        self.txtAreaAverbadaTerreno,
        self.txtAreaRealCasaOracao, self.txtareaRealTerreno]
        for objeto in listaObj:
            objeto.setValidator(validarReal)
    
    def populaComboIgreja(self, tudo=False):
        '''
        Essa função popula o combo igreja
        '''
        comando = QString("SELECT cod_relatorio, nome_localidade FROM \
        bens_imoveis WHERE e_administracao LIKE 'sim'")
        if tudo:
            comando = QString("SELECT cod_localidade, nome_localidade \
            FROM bens_imoveis")
        self.cmbAdministracao.clear()
        self.promptComando.exec_(comando)
        listaAdministracao = QStringList('') 
        while self.promptComando.next() :
            listaAdministracao << self.promptComando.value(0).toString()\
             + " - " + self.promptComando.value(1).toString()
        self.cmbAdministracao.addItems(listaAdministracao)
        
    def alt_diversos(self):
        '''Essa função altera os valores das chaves do dicionário
        quando os objetos checkbox são clicados, a função sender()
        retorna o objeto que enviou o sinal, como as chaves
        do dicionário tem os nomes dos objetos então fica fácil
        usar essa função pois as chaves correspondentes
        a cada objeto são alteradas de acordo 
        com o nome do objeto que enviou o sinal.
        '''
        if self.sender().isChecked() == True:
            enviador = unicode(self.sender().objectName(),
            'utf-8')
            self.dic[enviador] = QString("sim")
        else:
            enviador = unicode(self.sender().objectName(),
            'utf-8')
            self.dic[enviador] = u"não"                                                       
    
    def salvarDados(self):
        ''' Essa é a função que salva os dados do formulário
        '''
        comando = QString("INSERT INTO bens_imoveis(cod_relatorio,\
        nome_localidade,administracao,registro_imovel,e_administracao,\
        alvara_construcao,alvara_funcionamento,CEI,CND,contrato,escritura,\
        habite_se,projeto_arquitetonico,projeto_eletrico,projeto_estrutural,\
        projeto_hidraulico,projeto_incendio,registro,data_construcao,\
        situacao,area_real_terreno,area_averbada_terreno,areaReal_casaOracao,\
        areaAverbada_casaOracao,justificativaDificuldade,usuario) \
        VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)")
        administracao = QString()
        if self.cmbAdministracao.currentText() != "":
            administracao = self.cmbAdministracao.currentText().split(" - ")[1]
        self.promptComando.prepare(comando)
        self.promptComando.bindValue(0, self.txtcodRelatorio.text())
        self.promptComando.bindValue(1, self.txtNomeLocalidade.text().replace(" - ", "-"))
        self.promptComando.bindValue(2, administracao)
        self.promptComando.bindValue(3, self.txtRegistroImovel.text())
        self.promptComando.bindValue(4, self.dic["checkAdministracao"])
        self.promptComando.bindValue(5, self.dic["checkAlvaraConstrucao"])
        self.promptComando.bindValue(6, self.dic["checkAlvaraFuncionamento"])
        self.promptComando.bindValue(7, self.dic["checkCEI"])
        self.promptComando.bindValue(8, self.dic["checkCND"])
        self.promptComando.bindValue(9, self.dic["checkContrato"])
        self.promptComando.bindValue(10, self.dic["checkEscritura"])
        self.promptComando.bindValue(11, self.dic["checkHabitese"])
        self.promptComando.bindValue(12, self.dic["checkProjArquitetonico"])
        self.promptComando.bindValue(13, self.dic["checkProjEletrico"])
        self.promptComando.bindValue(14, self.dic["checkProjEstrutural"])
        self.promptComando.bindValue(15, self.dic["checkProjHidraulico"])
        self.promptComando.bindValue(16, self.dic["checkProjIncendio"])
        self.promptComando.bindValue(17, self.dic["checkRegistro"])
        self.promptComando.bindValue(18, self.conversor_data(self.txtDataConstrucao.text()))
        self.promptComando.bindValue(19, self.cmbSituacao.currentText())
        self.promptComando.bindValue(20, self.txtareaRealTerreno.text().replace(",", "."))
        self.promptComando.bindValue(21, self.txtAreaAverbadaTerreno.text().replace(",", "."))
        self.promptComando.bindValue(22, self.txtAreaRealCasaOracao.text().replace(",", "."))
        self.promptComando.bindValue(23, self.txtAreaAverbadaCasaOracao.text().replace(",", "."))
        self.promptComando.bindValue(24, self.textoJustificativa.toPlainText())
        self.promptComando.bindValue(25, self.usuario)
        if self.promptComando.exec_():
            id = str(self.promptComando.lastInsertId().toInt()[0])
            QMessageBox.warning(self, unicode("O número do registro gravado foi: ",
            "utf-8"), unicode("Número de Registro: " + id, "utf-8"))
            self.limpar_dados()
        else:
            textoErro = self.promptComando.lastError().text()
            QMessageBox.warning(self, unicode("Falha ao Gravar o Registro",
            "utf-8"), unicode("O código do erro foi: " + textoErro, "utf-8"))
        
    
    def limpar_dados(self, tudo=True):
        '''
        Essa função limpa os campos do formulário, o interessante
        é que eu resolvi usar laços for associados com listas,
        achei dessa forma uma maneira mais "pythoniana" :)
        '''
        # Esse laço coloca todas as chaves do dicionário como "não"
        for chaves in self.dic.keys(): 
            self.dic[chaves] = u"não"
        lista = self.findChildren(QLineEdit)
        #Esse laço pega a lista anterior de objetos texto e coloca 
        #em todos o texto vazio
        for objeto in lista: 
            objeto.setText('')
        # Essa lista pega os objetos "checkbox" e o laço seguinte 
        #desmarca todos eles.
        lista = self.findChildren(QCheckBox)
        for objeto in lista: 
            objeto.setChecked(False)
        if tudo:
            self.cmbAdministracao.setCurrentIndex(0)
            self.cmbAdministracao.setFocus()
            self.populaComboIgreja()
        self.textoJustificativa.setPlainText("")
        self.cmbSituacao.setCurrentIndex(0)


Eu usei um programinha bacana chamado colored para criar o código html para colar aqui no blog, isso vai ajudar demais agora pois colocarei todos os códigos aqui.

2 comentários:

Tomas disse...

Tu bem que podia colocar o pacote completo pra download.
Se não, ao menos o interfaces.ui.
Valeu.

Phiron disse...

Depois eu farei um exemplo onde não precise de interface com banco de dados e talzs, essa classe é dependente de outras, eu quis colocar apenas os exemplos dos métodos que podem ser utilizados.
Mas essa classe precisa de banco de dados e de ser inicializada em um MDI form, por isso eu postei apenas a classe, futuramente eu colocarei um exemplo menor e mais simples.