Google+ Seguidores

domingo, 30 de noviembre de 2014

Aplicacion grafica con pyqt4 y sqlite3 en python

    38

pyqt4 y sqlite3
Conexión pyqt4 y sqlite3
En la entrada anterior estuvimos viendo como crear una aplicación en Qt Designer y Python. También deje unos ejercicios para practicar con las aplicaciones gráficas.
Hoy la idea es crear una sencilla aplicación gráfica (también utilizando pyqt4 y python) y conectar dicha aplicación a una base de datos sqlite3 para que nuestros datos sean guardados y recuperados.

Funcionalidad de la aplicación:


En la aplicación se podrán guardar los datos de los clientes (Nombre, Apellido y Localidad). El cliente será guardado en una base de datos al presionar el botón Guardar.
Para ver todos los clientes almacenados en nuestra base de datos presionamos el botón Cargar.

 

Componentes de la aplicación:

Abrimos QtDesigner y creamos un nuevo Main Window. Tratar de dejarlo lo más parecido a la siguiente imagen:

Componentes de la aplicación
Componentes de la aplicación

4 - Etiquetas (Clientes, Nombre, Apellido, Localidad)
3 - LineEdit
2 - Botones (Guardar y Cargar)
1 - List Widget

ObjectName de los componentes:

Son los nombres con los que haremos referencia en el código

LineEdit - (lineEdit, lineEdit_2, lineEdit_3)
Botones - (btn_Guardar, btn_Cargar)
List Widget - (lista)

Guardamos el archivo con el nombre: conBase.ui

Creamos un nuevo archivo conBase.py en el IDE que nos guste más (tiene que estar en el mismo directorio que conBase.ui) y codeamos lo siguiente:

Código de la aplicación:


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

# Aplicacion grafica con sqlite3
# www.pythondiario.com
 
import sys
import sqlite3
from PyQt4 import QtCore, QtGui, uic

# Cargar nuestro archivo .ui
form_class = uic.loadUiType("conBase.ui")[0]

class MyWindowClass(QtGui.QMainWindow, form_class):
 def __init__(self, parent=None):
  QtGui.QMainWindow.__init__(self, parent)
  self.setupUi(self)
  self.btn_Guardar.clicked.connect(self.btn_Guardar_clicked)
  self.btn_Cargar.clicked.connect(self.btn_Cargar_clicked)
  self.IniciarBase()
  

 def IniciarBase(self):
  self.con = sqlite3.connect("/home/diego123/Escritorio/pyqt4/prueba.bd")
  self.cursor = self.con.cursor()
  self.cursor.execute ("""CREATE TABLE IF NOT EXISTS campos(NOMBRE TEXT NOT NULL, APELLIDO TEXT NOT NULL, LOCALIDAD TEXT NOT NULL)""" )
  self.con.commit()

 # Evento del boton Guardar
 def btn_Guardar_clicked(self):

  self.con = sqlite3.connect("/home/diego123/Escritorio/pyqt4/prueba.bd")
  self.cursor = self.con.cursor()

  # Datos
  self.nombre = str(self.lineEdit.text())
  self.apellido = str(self.lineEdit_2.text())
  self.localidad = str(self.lineEdit_3.text())
  self.datos = (self.nombre, self.apellido, self.localidad)

  # Inserta los datos en la tabla campos
  self.cursor.execute("INSERT INTO campos (nombre, apellido, localidad) VALUES (?,?,?)", self.datos)
  self.con.commit()

  # Quedan los campos vacios al guardar cliente
  self.lineEdit.setText("")
  self.lineEdit_2.setText("")
  self.lineEdit_3.setText("")

  self.con.commit()
  self.con.close()

 # Evento del boton Caragar
 def btn_Cargar_clicked(self):

  self.con = sqlite3.connect("/home/diego123/Escritorio/pyqt4/prueba.bd")
  self.cursor = self.con.cursor()
  
  # Se cargan los datos indicados de la tabla
  self.cursor.execute("SELECT NOMBRE, APELLIDO, LOCALIDAD FROM campos")

  # Al presionar el boton lo primero es borrar todos los datos
  self.lista.clear()

  # Se agregan los elementos al QListWidget
  for i in self.cursor:
   self.nombre = str(i[0])
   self.apellido = str(i[1])
   self.localidad = str(i[2]) 
   
   self.lista.addItem(self.nombre + " - " + self.apellido + " - " + self.localidad)

  self.con.commit()
  self.con.close()
   
 
app = QtGui.QApplication(sys.argv)
MyWindow = MyWindowClass(None)
MyWindow.show()
app.exec_()

Análisis del código:


En la parte superior importamos la biblioteca PyQt, sqlite3 y cargamos el archivo conBase.ui que generamos anteriormente con QtDesigner.

Creamos la clase MyWindowClass y le pasamos (QtGui.QMainWindow y form_class). El método __init__ configura la interfaz GUI. En esta función tenemos que conectar los controladores de eventos:

self.btn_Guardar.clicked.connect(self.btn_Guardar_clicked)
self.btn_Cargar.clicked.connect(self.btn_Cargar_clicked)
self.IniciarBase()

El método clicked.connect es llamado cuando el botón es presionado.

Funciones de nuestra aplicación:

def IniciarBase(self):
  self.con = sqlite3.connect("/home/diego123/Escritorio/pyqt4/prueba.bd")
  self.cursor = self.con.cursor()
  self.cursor.execute ("""CREATE TABLE IF NOT EXISTS campos(NOMBRE TEXT NOT NULL, APELLIDO TEXT NOT NULL, LOCALIDAD TEXT NOT NULL)""" )
  self.con.commit()

La función IniciarBase(), como su nombre lo indica, inicia la base de datos de nuestra aplicación, y es colocada en el método __init__ para que se inicie cuando ejecutemos nuestro programa.
Si no existe, se crea la tabla campos con 3 elementos (NOMBRE, APELLIDO, LOCALIDAD).
Si no sabes como funciona una base de datos Sqlite3 en python, te recomiendo que mires la siguiente entrada: Sqlite3 y Python

# Evento del boton Guardar
 def btn_Guardar_clicked(self):

  self.con = sqlite3.connect("/home/diego123/Escritorio/pyqt4/prueba.bd")
  self.cursor = self.con.cursor()

  # Datos
  self.nombre = str(self.lineEdit.text())
  self.apellido = str(self.lineEdit_2.text())
  self.localidad = str(self.lineEdit_3.text())
  self.datos = (self.nombre, self.apellido, self.localidad)

  # Inserta los datos en la tabla campos
  self.cursor.execute("INSERT INTO campos (nombre, apellido, localidad) VALUES (?,?,?)", self.datos)
  self.con.commit()

  # Quedan los campos vacios al guardar cliente
  self.lineEdit.setText("")
  self.lineEdit_2.setText("")
  self.lineEdit_3.setText("")

  self.con.commit()
  self.con.close()

La función btn_Guardar_clicked(self), se encargará de guardar los datos del cliente en nuestra tabla campos. Al presionar guardar se borran los contenidos de los lineEdit para llenar otro cliente.

# Evento del boton Caragar
 def btn_Cargar_clicked(self):

  self.con = sqlite3.connect("/home/diego123/Escritorio/pyqt4/prueba.bd")
  self.cursor = self.con.cursor()
  
  # Se cargan los datos indicados de la tabla
  self.cursor.execute("SELECT NOMBRE, APELLIDO, LOCALIDAD FROM campos")

  # Al presionar el boton lo primero es borrar todos los datos
  self.lista.clear()

  # Se agregan los elementos al QListWidget
  for i in self.cursor:
   self.nombre = str(i[0])
   self.apellido = str(i[1])
   self.localidad = str(i[2]) 
   
   self.lista.addItem(self.nombre + " - " + self.apellido + " - " + self.localidad)

  self.con.commit()
  self.con.close()

La función btn_Cargar_clicked(self), se encargará de mostrar en el List Widget, todos los clientes que hallamos ingresado.

Al final del código, necesitamos iniciar la interfaz gráfica:

app = QtGui.QApplication(sys.argv)
MyWindow = MyWindowClass(None)
MyWindow.show()
app.exec_()  

Espero que esta entrada les sea de ayuda para sus futuras aplicaciones en python. Saludos

38 comentarios:
Write comentarios
  1. Felicidades, lo ejecute y salio OK

    ResponderEliminar
  2. Excelente! para empezar a crear proyectos... Diego, me gustarìa que compartieras un metodo de PyQt para importar imagenes, es decir asignar una foto a cada ID en la base de datos! Agradecerìa la ayuda ya que la documentacion de QT esta en ingles :/ mi email es wwizka@hotmail.com

    ResponderEliminar
    Respuestas
    1. Hola, estuve buscando algo de información sobre como guardar imágenes en una base de datos Sqlite y encontré algunas discusiones sobre si es bueno o no guardar directamente las imágenes en la base de datos (se hace muy pesada). Algunos recomiendan usar Postgres que viene con un tipo de datos para las fotos. Otros recomiendan guardar las imágenes en una carpeta y en la base de datos guardar la ruta de dicha imagen.
      Quizá más adelante cree una entrada sobre este tema.
      Saludos

      Eliminar
  3. disculpa amigo estoy programando con python y me encontre con un problema me pide el modulo dockwidgets_rc

    y la verdad no lo encuentro

    ResponderEliminar
  4. Hola me gustaria saber como conectar con una base de datos en mysql y phpmyadmin gracias estoy empezando en la programacion

    ResponderEliminar
  5. Me parece interesante... Ahora cómo haría para actualizar un dato o en su caso, eliminarlo?

    ResponderEliminar
    Respuestas
    1. Hola, ya voy a realizar una entrada con modificación y eliminación. Saludos y gracias por visitar el blog.

      Eliminar
    2. Hola Diego! Soy Lucas. Primero queria felicitarte por el excelente laburo de la web. Tengo un par de dudas:
      1- A este mismo scrip le quiero agregar como mencionas la parte de modificacion y eliminacion.

      2- Como hago para ejecutar este programa sin hacerlo desde la consola?

      Gracias!

      Eliminar
    3. Hola Lucas, como estas? Gracias por visitar el blog. Todavía no he realizado el ABM completo de la aplicación. Ni bien me haga un tiempito agrego como eliminar y como modificar. Para la segunda pregunta, ¿Qué sistema operativo utilizas?
      Saludos!!!

      Eliminar
    4. Como estas Diego? Estoy usando Ubuntu Mate 16.04, desde la consola lo ejecuto con "python ******.pyc". Con respecto a lo de modificar o actualizar y eliminar, tome tu codigo como referencia pero me saltan algunos errores. Saludos!

      Eliminar
    5. Hola Gallito, todo bien por acá, tu? Cual es el error que te sale?
      Saludos!!!

      Eliminar
    6. Todo bien Diego! Te puedo pasar el archivo .py o te copio el código de lo que tengo hasta ahora?

      Eliminar
  6. Una pregunta a mi me da este error, como que no puede importar las librerias

    Traceback (most recent call last):
    File "C:/base/conBase.py", line 9, in
    from PyQt4 import QtCore, QtGui, uic
    ImportError: No module named PyQt4

    ResponderEliminar
  7. Hola, ya lo solucione en Windows era la versión de PyQt4.
    ahora tengo otro problema estoy en linux y me da este error. Me puedes ayudar? gracias

    Traceback (most recent call last):
    File "conBase.py", line 8, in
    class MyWindowClass(QtGui.QMainWindow, form_class):
    File "conBase.py", line 47, in MyWindowClass
    for i in self.cursor:
    NameError: name 'self' is not defined

    ResponderEliminar
    Respuestas
    1. Hola Marcelo, fijate que lo tengas bien instaldo, debe venir por ahí la mano: http://www.pythondiario.com/2013/11/como-instalar-pyqt4-en-windows-linux-y.html

      Saludos y gracias por visitar el blog.

      Eliminar
    2. Marcelo Bazan, no se si sea muy tarde pero para corregir "NameError: name 'self' is not defined" fíjate que estés respetando las indentaciones, en Python son muy importantes.

      Eliminar
  8. Hola Diego espero estes bien. me surgió una duda, en el siguiente código:

    self.con = sqlite3.connect("/home/diego123/Escritorio/pyqt4/prueba.bd")

    Me preguntaba de dónde obtuviste la ruta.
    En mi caso como yo tenia los archivos junto con la base de datos, solo puse:

    self.con = sqlite3.connect("base.bd")

    y me lanzó este error:

    File "C:\Users\Usuario1\Documents\PRACTICAS\programa de contactos con db\conBase.py", line 15, in IniciarBase
    self.con = sqlite3.connect("base.db")
    RuntimeError: maximum recursion depth exceeded while calling a Python object

    ¿Cómo podrías solucionarlo?

    Espero puedas apoyarme, gracias Diego.


    ResponderEliminar
  9. Amigo como podría hacer si quisiera por ejemplo eliminar datos agregados a la tabla desde la interfaz y no solo dentro del codigo?

    ResponderEliminar
  10. Este comentario ha sido eliminado por el autor.

    ResponderEliminar
  11. Muy buen tut! Siempre he hecho interfaces como éstas pero sólo con Tkinter; sin embargo, tenía el problema que no quedaban buen distribuidos los widgets con pack y grid. Ahora creo que con este tut se mejoran las cosas.
    Por cierto, también me gustaría saber como sería si quisiera botones para editar y borrar los registros, y además de trabajarlos en sqlite, cómo sería con Mysql, que sería mucho más seguro para mí.

    ResponderEliminar
  12. Hola, muy buena entrada, pero hay algo que no entiendo. Después de borrar los lineEdit haces un commit a la base de datos, ¿con que finalidad? Saludos

    ResponderEliminar
    Respuestas
    1. segun tengo entendido el commit es para hacer efectiva la escritura de los datos en la bd

      Eliminar
  13. saludos pido su ayuda si alguien sabe como puedo obtener la posicion de una celda de un qtablewidget seleccionandola espero haberme dado a entender

    ResponderEliminar
    Respuestas
    1. Hola crostow, quizá puedas revisar bien en la documentación oficial: http://pyqt.sourceforge.net/Docs/PyQt4/qtablewidget.html, Saludos y gracias por visitar el blog.

      Eliminar
    2. ok solucionado gracias por la informacion
      por cierto realize un pequeño punto de venta muy basico

      alta, modificacion , elimimacion de productos y usuarios y un pequeño corte con los productos vendido por dia

      me gustaria compartirlo como se haria bueno se se puede

      Eliminar
    3. Hola crostow, exclente. Puedes enviarme el código a la dirección: diegocaraballo84@gmail.com, con algún comentario y puedo agregarlo como una entrada, puedes pasarme tus datos de contacto para agregar tus créditos. Saludos y gracias por visitar el blog ;)

      Eliminar
  14. Hola crostow, también estoy interesado ver como armaste el proyecto, o por lo menos una parte de el, agradecido por el aporte.
    Mi dirección es: hugoguerrero03@gmail.com.

    ResponderEliminar
    Respuestas
    1. ya mande el codigo solo falta que lo agreguen

      Eliminar
    2. Excelente, esta semana lo bajo, reviso el código y lo subo. Gracias por el aporte ;)
      Saludos, Diego.

      Eliminar
    3. bueno ya subi el proyecto a git hub si aun les interesa esta es la direccion

      https://github.com/crostow/punto-de-venta

      Eliminar
    4. Hola, disculpa que no he podido publicar una entrada sobre tu app, he estado medio corto de tiempo. En cuanto me haga un tiempito la analizo bien y la subo. Gracias ;)

      Eliminar
  15. Hola que tal tengo este problema
    Espero alguien me pueda decir que es lo que estoy haciendo mal
    Al momento de ejecutar el codigo me aparece un error
    Traceback (most recent call last):
    File "C:/Proyecto/ConversionesTemp/conBase1.py", line 63, in btn_Cargar_clicked
    self.lista.clear()
    AttributeError: 'MyWindowClass' object has no attribute 'lista'
    Ese es el error que me aparece cuando doy click en el boton cargar

    ResponderEliminar
    Respuestas
    1. Hola, fijate que en QtDesigner hallas cambiado el nombre del List Widget a Lista. Saludos

      Eliminar
  16. saludos tendras el codigo para eliminar datos de lista ? y crear un boton que conduzca a otra ventana o a otro .ui gracias

    ResponderEliminar
    Respuestas
    1. Hola Alejandro, perdón la demora. Al momento no tengo nada de lo que pides. Ya crearé un ABM (ALTA, BAJA, MODIFICACIÓN). Saludos

      Eliminar
  17. Hola, para conectar con postgress puedo usar el mismo codigo? solo cambio la conexion?

    ResponderEliminar
    Respuestas
    1. Hola Marcos, además de la conexión, cambias las consultas (por ejemplo en insert). Fijate en la documentación oficial de Postgres. Saludos

      Eliminar

Tu comentario es importante y nos motiva a seguir escribiendo...

Entradas más recientes

© 2014 Mi diario Python. Designed by Bloggertheme9 | Distributed By Gooyaabi Templates
Powered by Blogger.