Desenvolvendo aplicações GUI simples em Python & Glade (PyGTK) com banco de dados SQLite

O objetivo deste artigo é mostrar de forma objetiva como realizar procedimentos básicos de programação, então vamos abordar a criação da parte gráfica do programa, vamos falar de como usar controles e eventos simples na nossa aplicação, como botões, caixas de textos, janelas, diálogos, listas, o básico necessário da linguagem Python e como fazer as principais operações com banco de dados.

[ Hits: 163.212 ]

Por: Perfil removido em 28/07/2010


Finalizando com a listagem



Por fim vamos ver como listar os registros no banco e exibí-los numa lista. No geral não tem nada de diferente dos arquivos que já vimos, a não ser o detalhe do componete GtkTreeView, que funciona tanto como treeview quanto como listview, que é como o usaremos. Vamos ver o arquivo inteiro, depois comentá-lo.

Arquivo: usuarioslista.py

#!/usr/bin/python
# -*- coding: utf-8 -*-

#Importação das bibliotecas
import pygtk
pygtk.require('2.0')
import gtk
from gtk import glade
import gobject
from sqlite3 import *

#Importação de arquivos do projeto
import funcoes as f
import usuarioscadastro

class UsuariosLista(gtk.Window):

#Método construtor
  def __init__(self, widget):
   #Inicializar
    super(UsuariosLista, self).__init__()

   #Carrega arquivo glade
    GLADE_FILE = f.CaminhoGlade + 'usuarioslista.glade'
    gui = glade.XML(GLADE_FILE, 'winUsuariosLista')

   #Associa controles
    self.win = gui.get_widget('winUsuariosLista')
    self.btnSair = gui.get_widget('btnSair')
    self.lstUsuarios = gui.get_widget('lstUsers')
    self.btnAlterar = gui.get_widget('btnAlterar')
    self.btnExcluir = gui.get_widget('btnExcluir')

   #Abre Janela
    self.win.show_all()

   #Formata controle lista
    self.modLista = gtk.TreeStore(gobject.TYPE_INT,
                                  gobject.TYPE_STRING,
                                  gobject.TYPE_STRING)

    self.lstUsuarios.set_model(self.modLista)
    self.lstUsuarios.set_headers_visible(True)

   #Cria colunas da lista
    self.CriarColuna('ID', 0)
    self.CriarColuna('Usuário', 1)
    self.CriarColuna('Nome completo', 2)

   #Adiciona scroll à TreeView
    self.lstUsuarios.set_rules_hint(True)

   #Carrega usuários
    self.ListaUsers()

   #Estado inicial
    self.btnAlterar.set_sensitive(False)
    self.btnExcluir.set_sensitive(False)
    self.win.set_focus(self.btnSair)

   #Eventos dos controles
    self.btnSair.connect('clicked', lambda *a: self.Fechar())
    self.btnAlterar.connect('clicked', lambda *a: self.AlterarUsuario(widget))
    self.lstUsuarios.connect('cursor_changed', lambda *a: self.AtivaBotoes(True))
    self.lstUsuarios.connect('row_activated', lambda *a: self.AlterarUsuario(widget))
    self.btnExcluir.connect('clicked', lambda *a: self.Excluir())


#Excluir
  def Excluir(self):
    campo, item = self.lstUsuarios.get_selection().get_selected()
    if (item != None):
      myNomeExc = campo.get_value(item, 1)
      if f.MsgConfirmacao(self.win, "Deseja realmente excluir " + myNomeExc + "?"):
        myID = campo.get_value(item, 0)
        if myID != f.usuariologadoid:
          f.Mensagem(self.win, "Você só pode excluir seu próprio usuário.")
        else:
          f.query.execute("DELETE FROM usuarios WHERE id = " + str(myID))
          f.cnx.commit()
          #Lista os usuarios
          self.ListaUsers()
    else:
      f.Mensagem(self.win, "Nenhum ítem foi selecionado.")


#Ativa botoes
  def AtivaBotoes(self, Ativo):
    self.btnAlterar.set_sensitive(Ativo)
    self.btnExcluir.set_sensitive(Ativo)


#Fecha janela
  def Fechar(self):
    self.win.destroy() == True


#Alterar usuario
  def AlterarUsuario(self, widget):
    campo, item = self.lstUsuarios.get_selection().get_selected()
    if (item != None):
      myID = campo.get_value(item, 0)
      if myID != f.usuariologadoid:
        f.Mensagem(self.win, "Você só pode alterar seu próprio usuário.")
      else:
        myNome = campo.get_value(item, 1)
        usuarioscadastro.UsuariosCadastro(widget, False, myID, self.win, self)
        self.win.set_focus(self.lstUsuarios)
    else:
      f.Mensagem(self.win, "Nenhum ítem foi selecionado.")


#Cria coluna da lista
  def CriarColuna(self, titulo, id):
    renderer = gtk.CellRendererText()
    column = gtk.TreeViewColumn(titulo, renderer, text = id)
    column.set_resizable(False)
    self.lstUsuarios.append_column(column)


#Lista usuários
  def ListaUsers(self):
    self.modLista.clear()

   #Executa query
    f.query.execute('SELECT id, user, nome FROM usuarios ORDER BY user DESC')

   #Preenche a lista
    for row in f.query:
      myiter = self.modLista.insert_after(None, None)
      self.modLista.set_value(myiter, 0, row[0])
      self.modLista.set_value(myiter, 1, row[1])
      self.modLista.set_value(myiter, 2, row[2])

Então primeiro vamos comentar a criação da nossa lista. O componente foi adicionado no arquivo ".glade" vazio, as colunas e a formatação das mesmas são criadas via programação no bloco:

    #Formata controle lista
    self.modLista = gtk.TreeStore(gobject.TYPE_INT,
                                  gobject.TYPE_STRING,
                                  gobject.TYPE_STRING)

    self.lstUsuarios.set_model(self.modLista)
    self.lstUsuarios.set_headers_visible(True)

    #Cria colunas da lista
    self.CriarColuna('ID', 0)
    self.CriarColuna('Usuário', 1)
    self.CriarColuna('Nome completo', 2)

    #Mostra barras de rolagem na lista
    self.lstUsuarios.set_rules_hint(True)

Note que temos aí uma função CriarColuna, que foi criado pra não repetirmos código, já que a criação de cada coluna usa os mesmos comandos praticamente. Esta função é declarada mais abaixo no arquivo:

  #Cria coluna da lista

  def CriarColuna(self, titulo, id):
    renderer = gtk.CellRendererText()
    column = gtk.TreeViewColumn(titulo, renderer, text = id)
    column.set_resizable(False)
    self.lstUsuarios.append_column(column)

Por fim temos a função ListaUsers, onde fazemos um loop com os resultados da query no banco e inserimos linha por linha:

  #Lista usuários
  def ListaUsers(self):
    self.modLista.clear()

    #Executa query
    f.query.execute('SELECT id, user, nome FROM usuarios ORDER BY user DESC')

    #Preenche a lista
    for row in f.query:
      myiter = self.modLista.insert_after(None, None)
      self.modLista.set_value(myiter, 0, row[0])
      self.modLista.set_value(myiter, 1, row[1])
      self.modLista.set_value(myiter, 2, row[2])

E basicamente é isso, procurei detalhar o básico de forma objetiva. Talvez tenha deixado alguma dúvida pois o assunto é realmente longo para esmiuçar, por isso procurei expor um código o mais auto-explicável possível, e me coloco à disposição pra pra ajudar no que for preciso pra entender melhor. E finalmente, vai um print do aplicativo:
Linux: Desenvolvendo aplicações GUI simples em Python & Glade (PyGTK) com banco de dados SQLite
Post original no meu blog: Desenvolvendo aplicações GUI simples em Python & Glade (PyGTK) com banco de dados SQLite - pedro-araujo.com

Página anterior    

Páginas do artigo
   1. Introdução
   2. Por que Python?
   3. Preparando o ambiente
   4. Dando forma à aplicação
   5. Agora vamos programar
   6. Continuando a programar
   7. Finalizando com a listagem
Outros artigos deste autor

Slackware - Instalação com Tagfiles

Arquivos de configuração de rede - Parte I - /etc/hosts

Projeto Xen - Visão Geral

Instalando a impressora Canon i250 no Linux

Swing e gerenciadores de layout

Leitura recomendada

Interagindo com servidores HTTP com Python

Introdução ao clib (Command Line Book)

Alimentando Desktopcouch com Zeitgeist

Esteganografia e Esteganálise: transmissão e detecção de informações ocultas em imagens digitais

Programe em Python no jogo Minecraft com seu filho ou sozinho

  
Comentários
[1] Comentário enviado por fonini em 29/07/2010 - 08:27h

Parabéns pelo excelente artigo!

[2] Comentário enviado por balani em 29/07/2010 - 09:40h

Excelente artigo, estou iniciando em Python, seu artigo me ajudará muito, nesse aprendizado.

Parabens!

Abraços


Adriano R. Balani

[3] Comentário enviado por gtuxed em 29/07/2010 - 12:34h

Bom artigo, parabéns.

Estes dias fiz meu primeiro aplicativo com PyGTK e apesar de também ser iniciante em python, não achei muito difícil exceto por ainda achar as estruturas liststore/treestore um pouco "overkill" rsrs.

Falando mais sobre estas estruturas, acho que apesar da flexibilidade que elas oferecem, deveria haver uma interface mais simples para coisas mais pragmáticas.

Mas isso é mais um problema com GTK do que com PyGTK (que é apenas um binding).

hehe, olha só como é complexo criar uma simples lista e apresentar...

##

# Criamos um modelo ListStore(<tipo>,<tipo>,...)
liststore = gtk.ListStore(str)

# Baseado no modelo criamos uma treeview
treeview = gtk.TreeView(liststore)

# Precisamos criar um "renderizador" (será que estou usando blender, engine 3d, etc.? rsrs)
textrenderer = gtk.CellRendererText()

# Adicionamos a coluna ao treeview
column = gtk.TreeViewColumn('Nome da coluna', textrenderer, text=0)
treeview.append_column(column)

# Adicionamos valores à lista
for row in ['a','b','c']:
itt = liststore.append([row])

##

Poderia ser assim:

##

# Criamos a lista
list = gtk.List(str)

# Adicionamos valores à ela
list.append('teste')

##

Da pra fazer isso facilmente, mas acho que isso já deveria existir rsrs

[4] Comentário enviado por gomes-fdr em 29/07/2010 - 16:26h

Muito bom o seu artigo, parabens.

Para mim servirá como material de apoio para o inicio de aplicativos baseados em Python(desktop).

Saudações.

[5] Comentário enviado por albfneto em 01/08/2010 - 18:48h

émuitobom esse artigo.! 10

[6] Comentário enviado por Lisandro em 21/12/2010 - 09:05h

Parabéns pelo artigo. Muito Bom.

[7] Comentário enviado por quemsoueu em 06/07/2012 - 08:18h

Cara seu artigo abriu meus olhos eu tava quase desistindo de desenvolver o software.
A dúvida é com o tkinter eu consigo rodar ele no windows como java, entretanto como faço para rodar ele no windows ele foi escrito com o pygtk e glade, e preciso rodar numa estação Win, acaso você já fez isso?

[8] Comentário enviado por leo523 em 10/06/2013 - 10:17h

Ótimo post, mas atualmente o modo é um pouco diferente, ao inves de usar a biblioteca glade.XML para chamar o xml, usa-se o gtk.builder.

Respondendo o comentário acima, para distribuir no Windows vc deve instalar o pygtk completo que esta neste link :
http://ftp.gnome.org/pub/GNOME/binaries/win32/pygtk/2.24/

[9] Comentário enviado por wladimir58 em 15/06/2016 - 16:27h

Nunca consegui usar as interfaces do Glade nos meus programas em Python




Contribuir com comentário