Ir para conteúdo

klonder

Members
  • Total de itens

    969
  • Registro em

  • Última visita

  • Dias vencidos

    2

Posts postados por klonder


  1. Olá a todos!

    Estou há 3 dias pesquisando sobre como assinar digitalmente um arquivo pdf com Python, porém nenhuma proposta funcionou no Python 3.8.

     

    O meu problema consiste no seguinte:

    Crio contratos no word e salvo no formato PDF em uma pasta.

    O que eu preciso é criar um aplicativo em Python que abra um arquivo pdf já criado e assine-o digitalmente através de um Certificado Digital pfx. Essa assinatura deveria ser inserida no final de cada documento. Já tentei várias ferramentas, porém nenhuma funcionou no Python 3.8. Alguém tem conhecimento sobre o assunto, utiliza, ou saberia dar alguma dica? Obrigado!


  2. Aproveitando o exemplo acima, deixo outra possibilidade para controle de eventos focusIn/focusOut. Com o método focusChanged signal of QApplication, foi necessário fazer algumas adaptações, mas deixei o código comentado para facilitar a referência:

     

    from PyQt5 import QtGui, QtCore, QtWidgets
    from PyQt5.QtWidgets import QApplication, QWidget, QMainWindow, QComboBox, QLineEdit, QCompleter
    from PyQt5.QtCore import QSize, Qt, QSortFilterProxyModel, QStringListModel
    
    class Ui_Autocomplete(QMainWindow):
        def __init__(self):
            super().__init__()
            self.initUI()
    
        def initUI(self):
            self.setGeometry(300, 200, 800, 600)
            self.setWindowTitle('Autocomplete com combobox')
      
            self.cboxEstado = QComboBox(self)
            self.cboxEstado.move(50, 50)
            self.cboxEstado.addItem("Acre")
            self.cboxEstado.addItem("Amazonas")
            self.cboxEstado.addItem("Amapá")
            self.cboxEstado.addItem("Pará")
            self.cboxEstado.addItem("Rondônia")
            self.cboxEstado.addItem("Roraima")
            self.cboxEstado.addItem("Tocantins")
    
            self.cboxEstado.addItem("Distrito Federal")
            self.cboxEstado.addItem("Goiás")
            self.cboxEstado.addItem("Mato Grosso")
            self.cboxEstado.addItem("Mato Grosso do Sul")
    
            self.cboxEstado.addItem("Alagoas")
            self.cboxEstado.addItem("Bahia")
            self.cboxEstado.addItem("Ceará")
            self.cboxEstado.addItem("Maranhão")
            self.cboxEstado.addItem("Piauí")
            self.cboxEstado.addItem("Pernambuco")
            self.cboxEstado.addItem("Paraíba")
            self.cboxEstado.addItem("Rio Grande do Norte")
            self.cboxEstado.addItem("Sergipe")
    
            self.cboxEstado.addItem("Paraná")
            self.cboxEstado.addItem("Rio Grande do Sul")
            self.cboxEstado.addItem("Santa Catarina")
    
            self.cboxEstado.addItem("Espírito Santo")
            self.cboxEstado.addItem("Minas Gerais")
            self.cboxEstado.addItem("São Paulo")
            self.cboxEstado.addItem("Rio de Janeiro")
            
            self.cboxEstado.setEditable(True)
            self.cboxEstado.completer().setCompletionMode(QCompleter.PopupCompletion)
            self.cboxEstado.completer().setFilterMode(Qt.MatchContains)
            self.cboxEstado.completer().setCaseSensitivity(QtCore.Qt.CaseInsensitive)
            #self.cboxEstado.focusOutEvent = self.pedeuFoco
            QtWidgets.qApp.focusChanged.connect(self.on_focusChanged)
            
            self.leRegiao = QLineEdit(self)
            self.leRegiao.move(250,50)
            self.leRegiao.resize(200, 22)
    
            
        def on_focusChanged(self, old, now):
            if now == self.leRegiao:
                self.leRegiao.setText(self.cboxEstado.currentText())
    
            if old == self.cboxEstado:
                occur = 0
                for i in range(len(self.cboxEstado)):
                    if self.cboxEstado.currentText() == self.cboxEstado.itemText(i):
                        occur = occur+1
                if occur == 0:
                    self.leRegiao.setText("")
                    self.cboxEstado.lineEdit().setFocus()
                    self.cboxEstado.lineEdit().selectAll()
                #else:
                    #Retira o cursor do widget
                    #QComboBox.focusOutEvent(self.cboxEstado,event)
    
                
        #def pedeuFoco(self,event):
            #occur = 0
            #for i in range(len(self.cboxEstado)):
                #if self.cboxEstado.currentText() == self.cboxEstado.itemText(i):
                    #occur = occur+1
            #if occur == 0:
                #self.cboxEstado.lineEdit().setFocus()
                #self.cboxEstado.lineEdit().selectAll()
            #else:
                ##Retira o cursor do widget
                #QComboBox.focusOutEvent(self.cboxEstado,event)
            
    if __name__ == '__main__':
        import sys
        app = QApplication(sys.argv)
        mainWin = Ui_Autocomplete()
        mainWin.show()
        sys.exit(app.exec_())

     

     

     

     


  3. Olá a todos(as)!

    Estava há 3 dias pesquisando sobre como resolver um problema que estava enfrentando em meu sistema, que consistia no seguinte:

    Implantar um Combobox com dados vindos do banco. Esse combobox deveria ser editável e apresentar os valores em seu popup suspenso. À medida em que o usuário fosse digitando, o autocomplete faria a busca em todos os valores já cadastrados e mostraria os compatíveis (procedimento até então comum em qualquer autocomplete). Todavia, o combobox só poderia perder o foco caso o texto inserido fosse exatamente igual a um dos valores existentes no popup, ou seja, não poderia ser  inserido nada que já não estivesse cadastrado anteriormente e presente na lista de valores.

    Após muito pesquisar, cheguei a um resultado muito satisfatório que compartilho com vocês, visto que varri a internet inteira à procura desse código e não encontrei em lugar nenhum. PyQt5 é extremamente pobre em tutoriais, principalmente em português.

     

    Segue o código que poderá ajudar quem precise:

    from PyQt5 import QtGui, QtCore, QtWidgets
    from PyQt5.QtWidgets import QApplication, QWidget, QMainWindow, QComboBox, QLineEdit, QCompleter
    from PyQt5.QtCore import QSize, Qt, QSortFilterProxyModel, QStringListModel
    
    class Ui_Autocomplete(QMainWindow):
        def __init__(self):
            super().__init__()
            self.initUI()
    
        def initUI(self):
            self.setGeometry(300, 200, 800, 600)
            self.setWindowTitle('Autocomplete com combobox')
      
            self.cboxEstado = QComboBox(self)
            self.cboxEstado.move(50, 50)
            self.cboxEstado.addItem("Acre")
            self.cboxEstado.addItem("Amazonas")
            self.cboxEstado.addItem("Amapá")
            self.cboxEstado.addItem("Pará")
            self.cboxEstado.addItem("Rondônia")
            self.cboxEstado.addItem("Roraima")
            self.cboxEstado.addItem("Tocantins")
    
            self.cboxEstado.addItem("Distrito Federal")
            self.cboxEstado.addItem("Goiás")
            self.cboxEstado.addItem("Mato Grosso")
            self.cboxEstado.addItem("Mato Grosso do Sul")
    
            self.cboxEstado.addItem("Alagoas")
            self.cboxEstado.addItem("Bahia")
            self.cboxEstado.addItem("Ceará")
            self.cboxEstado.addItem("Maranhão")
            self.cboxEstado.addItem("Piauí")
            self.cboxEstado.addItem("Pernambuco")
            self.cboxEstado.addItem("Paraíba")
            self.cboxEstado.addItem("Rio Grande do Norte")
            self.cboxEstado.addItem("Sergipe")
    
            self.cboxEstado.addItem("Paraná")
            self.cboxEstado.addItem("Rio Grande do Sul")
            self.cboxEstado.addItem("Santa Catarina")
    
            self.cboxEstado.addItem("Espírito Santo")
            self.cboxEstado.addItem("Minas Gerais")
            self.cboxEstado.addItem("São Paulo")
            self.cboxEstado.addItem("Rio de Janeiro")
            
            self.cboxEstado.setEditable(True)
            self.cboxEstado.completer().setCompletionMode(QCompleter.PopupCompletion)
            self.cboxEstado.completer().setFilterMode(Qt.MatchContains)
            self.cboxEstado.completer().setCaseSensitivity(QtCore.Qt.CaseInsensitive)
            self.cboxEstado.focusOutEvent = self.pedeuFoco
    
            self.leRegiao = QLineEdit(self)
            self.leRegiao.move(250,50)
            self.leRegiao.resize(200, 22)
    
        def pedeuFoco(self,event):
            occur = 0
            for i in range(len(self.cboxEstado)):
                if self.cboxEstado.currentText() == self.cboxEstado.itemText(i):
                    occur = occur+1
            if occur == 0:
                self.cboxEstado.lineEdit().setFocus()
                self.cboxEstado.lineEdit().selectAll()
            else:
                #Retira o cursor do widget
                QComboBox.focusOutEvent(self.cboxEstado,event)
            
    if __name__ == '__main__':
        import sys
        app = QApplication(sys.argv)
        mainWin = Ui_Autocomplete()
        mainWin.show()
        sys.exit(app.exec_())

     

     


  4. Boas galera!

    Vou deixar aqui um código que acabei de criar de um método que recebe a data de nascimento em formato de string e retorna a idade. Eu tinha esse código em JAVA, fiz umas melhorias e adaptei para Python, para o novo sistema que estou desenvolvendo.

    Deixo aí para quem precisar e também para minhas pesquisas futuras:

    O método retorna a idade no padrão: AAa | AAa MMm | AAa MMm DDd, exemplos: 38a | 38a 14m | 38a 14m 5d

    Deixei o parâmetro "tipo" podendo receber "a", "m", "d" apenas para facilitar a referência a "anos", "meses" e "dias", mas sintam-se à vontade para alterar depois!

    Boa sorte!

    from datetime import datetime,date
    
    
    def calcularIdade(self,dtYYYYMMDD,tipo):
            #dtYYYYMMDD: string de data no formato YYYY-MM-DD (exemplo: padrão SQL)
            #tipo: Pode receber "a","m","d" -> a: retorna YYa | m: retorna YYa MMd | d: retorna YYa MMm DDd
    
            dtDN = datetime.strptime(dtYYYYMMDD, '%Y-%m-%d').date()
            dtHoje = date.today()
    
            anoNasc = int(dtDN.strftime('%Y'))
            anoHoje = int(dtHoje.strftime('%Y'))
            mesNasc = int(dtDN.strftime('%m'))
            mesHoje = int(dtHoje.strftime('%m'))
            diaNasc = int(dtDN.strftime('%d'))
            diaHoje = int(dtHoje.strftime('%d'))
            dtNiver = datetime.strptime(str(anoHoje)+"-"+str(mesNasc)+"-"+str(diaNasc), '%Y-%m-%d').date()
    
            diffAnos = anoHoje-anoNasc
            diffMeses = mesHoje-mesNasc        
            diffDias = diaHoje-diaNasc
    
            if dtHoje<dtNiver:#Ainda não fez aniversário esse ano!
                diffAnos = anoHoje-anoNasc-1#Corrigindo o ano, pois ainda não fez aniversário
                diffMeses = 12+diffMeses#Corrigindo os meses/diffMeses é negativo!!!
    
            if diaHoje < diaNasc:#O mês ainda não virou
                diffMeses = diffMeses-1                        
                #Para o cálculo dos dias, é importante avaliar uma série de variáveis: Mês com 28,20,30 ou 31 dias
                mes_anterior_31d = [1,2,4,6,9,11]
                mes_anterior_30d = [5,7,8,10,12]
                if mesHoje in mes_anterior_31d:
                    diffDias = (31-diaNasc)+diaHoje
                elif mesHoje in mes_anterior_30d:
                    diffDias = (30-diaNasc)+diaHoje
                else:
                    if anoHoje%4 == 0:#Cálculos para anos bissextos
                        diffDias = (29-diaNasc)+diaHoje
                    else:#Anos não bissextos
                        diffDias = (28-diaNasc)+diaHoje
    
            if tipo == "a":
                return str(diffAnos)+"a"
            elif tipo == "m":
                return str(diffAnos)+"a "+str(diffMeses)+"m "
            else:
                return str(diffAnos)+"a "+str(diffMeses)+"m "+str(diffDias)+"d"

    Exemplo de chamada:

    print(self.calcularIdade("1981-09-11","d"))

     


  5. Após muita, muita pesquisa, vou deixar um código de um template com 3 colunas verticais, sendo que a coluna do meio responde ao tamanho da janela e as laterais podem responder ao tamanho ou serem fixas (vai do gosto do desenvolvedor). Há também a possibilidade de alterar rapidamente a posição entre as colunas laterais, bastando alterar o float de cada uma delas, sem mexer na marcação.

    Motivo do post: Pode ser que ajude alguém com o mesmo problema. Postarei também para minhas consultas futuras.

    Motivo 2: O site do Maujor tem um bom exemplo (https://www.maujor.com/tutorial/qqer-ordem-3colunas.php), porém não consegui manter as colunas laterais fixas. Além disso, para alterar as colunas de lugar é necessário fazer contas, mexer com números, distância dos widths, etc. Não é complexo, mas considerei o código abaixo mais simples, pois basta alterar os floats conforme descrito abaixo. Deixo a referência do site a quem interessar.

    Motivo 3: Ainda no site do Maujor (https://www.maujor.com/layout3col.shtml) há esse exemplo que quase atendeu o meu problema, porém é muito complexo e a maneira que encontrei também considerei mais fácil (já utilizei muito esse esquema em projetos anteriores, porém complica na responsividade).

    Motivo 4: Principal referência que resolveu todos os meus problemas: https://www.richardbarros.com.br/css/css-truques-para-dominar-a-propriedade-float. Esse site foi a "Eureka" para eu deixar exatamente conforme eu queria.

     

    Segue o código:

     

    CSS:

    <style>
    #navGlobal {
    	height:400px;
    }
    #navEsquerda {
        float:left;
        width:250px;/*Está em pixels, mas poderia deixar em porcentagem: ex: 20% */
        background:#FFF;
        height:100%;
    }
    #navDireita {
        /*margin-left:var(--margemEsquerda); Opcional*/
        word-break: break-all; word-wrap: break-word;
    	height:100%;
    }
    #navLinks {
        float:right;
        width:200px;/*Está em pixels, mas poderia deixar em porcentagem: ex: 20% */
        height:100%;
        background:#CCC;    
    }
    #navConteudo {
    	overflow:auto;
    	height:100%;
    	background:#EFEFEF;
    }
    </style>

     

    HTML:

    <div id="navGlobal">
    	<div id="navEsquerda">Menu</div>
    	<div id="navDireita">
    		<div id="navLinks">Links</div>
    		<div id="navConteudo">Conteúdo do meu site</div>
    	</div>
    </div>

    Nos comentários do código, informei o que alterar para manter as colunas laterais fixas ou em porcentagem, bem como para trocá-las de lugar uma lateral com o outra.

    Deixei cores vibrantes como modelo para o usuário alterar depois.

    Abraços a todos(as).


  6. Para resolver acentos no tcpdf, no header e no footer, basta utilizar utf8_encode no texto. Também serve para o código html que retorna da variável.

     

    Ex: utf8_encode('<< MEU TÍTULO >>')

     

    Abaixo um exemplo para a função Footer, para permitir a palavra "Página" na frase "Página x de y".

    public function Footer() {
    $this->SetY(-15);
    $this->SetFont('helvetica', 'I', 8);
    $this->Cell(0, 10,
                utf8_encode('Página'). $this->getAliasNumPage() . ' de ' .
                $this->getAliasNbPages(), 0, false, 'C', 0, '',
                0, false, 'T', 'M');
    }

    Se seu código HTML estiver dentro de uma variável do PHP, como por exemplo $html, basta aplicar a mesma rotina:

    $html = utf8_encode($html);
    $pdf->WriteHTMLCell(192,0,9,'',$html,0,1);

     


  7. Desenvolvo em Java. Tenho sistema pronto para Gerenciamento de Home Care. Gera XML nos padrões TISS, tenho conhecimento de muita coisa relacionada a ANS, guias TISS, XML, XLS. Esse sistema gera prescrições, orçamentos, aditivos, etc.

    Poderia adaptar perfeitamente para clínicas. Ficaria show de bola!

    Caso queira uma demonstração:

    https://youtu.be/PJ3LAtjAmzk

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.