2

Deseo cargar los datos de una tabla, el problema surge cuando presiono el botón me tira el siguiente error:

C:\Users\marco\Downloads\Python\PyQt>python nueva.py TypeError: loadData() takes 0 positional arguments but 2 were given

Este es mi código:

from PyQt4 import QtCore, QtGui
import sqlite3
try:
    _fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
    def _fromUtf8(s):
        return s

try:
    _encoding = QtGui.QApplication.UnicodeUTF8
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig)

class Ui_MainWindow(object):
    def loadData():
        connection = sqlite3.connect("condo2.db")
        query = "SELECT * FROM aptos"
        result =connection.execute(query)
        self.tableWidget.setRowCount(0)
        for row_number, row_data in enumerate(result):
            self.tableWidget.insertRow(row_number)
            for column_number, data in enumerate(row_data):
                self.tableWidget.setItem(row_number, column_number, QtWidgets.QTableWidgetItem(str(data)))

        connection.close()
    def setupUi(self, MainWindow):
        MainWindow.setObjectName(_fromUtf8("MainWindow"))
        MainWindow.resize(800, 600)
        self.centralwidget = QtGui.QWidget(MainWindow)
        self.centralwidget.setObjectName(_fromUtf8("centralwidget"))
        self.lista = QtGui.QTableWidget(self.centralwidget)
        self.lista.setGeometry(QtCore.QRect(30, 30, 721, 341))
        self.lista.setRowCount(111)
        self.lista.setColumnCount(4)
        self.lista.setObjectName(_fromUtf8("lista"))
        self.pushButton = QtGui.QPushButton(self.centralwidget)
        self.pushButton.setGeometry(QtCore.QRect(300, 460, 75, 23))
        self.pushButton.setObjectName(_fromUtf8("pushButton"))
        self.pushButton.clicked.connect(self.loadData)
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtGui.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 21))
        self.menubar.setObjectName(_fromUtf8("menubar"))
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtGui.QStatusBar(MainWindow)
        self.statusbar.setObjectName(_fromUtf8("statusbar"))
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow", None))
        self.pushButton.setText(_translate("MainWindow", "cerrar", None))


if __name__ == "__main__":
    import sys
    app = QtGui.QApplication(sys.argv)
    MainWindow = QtGui.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())

Uso Python 3.4 junto a PyQt 4.

FJSevilla
  • 55,603
  • 7
  • 35
  • 58
Marco Salazar
  • 59
  • 1
  • 9

1 Answers1

1

El error se lanza básicamente porque llamas a loadData() como un método de instancia:

self.pushButton.clicked.connect(self.loadData)
                                ^^^^^
                               

De hecho debería ser un método de instancia (ya que acedes y modificas atributos de tu clase), el problema es que para ser un método de instancia debe recibir como primer parámetro la instancia de la clase a la que pertenece. Generalmente se usa self por convención para nombrar este argumento. No especificas el parámetro self al declararlo pero si que se le pasa al llamarlo con self.loadData().

El evento QPushButton.clicked envia un segundo argumento que es el estado del botón. Podrias omitirlo pero es importante recordarlo en algunos casos como al usar lambda para pasar argumentos, por ejemplo. En definitiva debes declarar el método como def loadData(self, state). Para saber más del significado de self mírate:

¿Para qué se utiliza self en POO en Python?

Tienes otros errores en este método:

  • El atributo self.tableWidget no existe, supongo que te debes referir a self.lista, que es tu instancia de QTableWidget.

  • QTableWidgetItem en PyQt 4 no se encuentra dentro del módulo QtWidgets (esto es así solo para PyQt 5 en adelante) sino dentro de QtGui.

El método loadData debe ser:

def loadData(self, state):
    with sqlite3.connect('condo2.db') as con:
        cursor = con.cursor()
        cursor.execute("SELECT * FROM aptos")
        self.lista.setRowCount(0)
        for row_number, row_data in enumerate(cursor):
            self.lista.insertRow(row_number)
            for column_number, data in enumerate(row_data):
                self.lista.setItem(row_number, column_number, QtGui.QTableWidgetItem(str(data)))
                self.lista.resizeColumnToContents(column_number)

    
    

El resto del código es correcto.


Edición:

El error:

sqlite3.OperationalError: no such table: aptos.

indica que la tabla no existe.

Asegúrate que la base de datos original esta en el mismo directorio que tu script de pyqt (misma carpeta). En caso contrario pasa la ruta absoluta o relativa adecuada. Si has ejecutado el script en otro directorio donde no estaba el archivo de la base de datos original (o el nombre no coincide), al no encontrar la base de datos te crea una base de datos con ese nombre pero vacía y se conecta a ella. Claro está, no tiene tabla alguna.

El error:

sqlite3.DatabaseError: file is encrypted or is not a database

es debido muy a menudo por usar una versión distinta de SQLite a la que usa la API de tu versión de Python. Comúnmente se debe a modificar o crear la base de datos con versiones no compatibles de sqlite CLI, API de C++, etc. Si se debe a esto, lo mas simple es crear o modificar la bd desde el propio Python.

FJSevilla
  • 55,603
  • 7
  • 35
  • 58
  • hola de nuevo, gracias por reponder y por los tips. y la lectura. he modificado el codigo segun tus recomendacion pero me salea hora este error: File "nueva.py", line 30, in loadData result =connection.execute(query) sqlite3.OperationalError: no such table: aptos. y la tabla existe en la base de datos porq logre cargarla en un listview – Marco Salazar Oct 02 '17 at 17:13
  • HOLA siguiendo lo que me dices, me di cuenta que me creaba una base de datos en vez de tomar la que ya existia. la modifique y le hice la tabla aptos y le importe los registros desde un archivo csv. y al ejecutar el scrip con el codigo que me enviaste arroja esto: C:\Users\marco\Downloads\Python\PyQt>python listatablas.py Traceback (most recent call last): File "listatablas.py", line 5, in cursor.execute("select name from sqlite_master where type = 'table'") sqlite3.DatabaseError: file is encrypted or is not a database – Marco Salazar Oct 02 '17 at 19:46
  • Hola, ya he resuleto el problema, la base de datos que creo el script la modifique con sqlite manager de mozilla, para poder poblar la tabla con los datos luego ejecute de nuevo e lscript y cargo los datos en el table. ahora me falta lo que en un principio me trajo hasta aqui y es ajustar el ancho de las columnas..... GRACIAS mil por tu apoyo y paciencia. no es algo que se me haga tan facil pero poco a poco llegare a ser tan bueno como tu. Saludos – Marco Salazar Oct 02 '17 at 20:42
  • exacto asi mismo es que cada columna se adapte al ancho del item mas largo q haya en la tabla. – Marco Salazar Oct 02 '17 at 22:24
  • @MarcoSalazar si es solo eso puedes usar el método `resizeColumnToContents`. He editado la pregunta modificando la función `loadData`. Mira a ver si cumple con lo que quieres. – FJSevilla Oct 02 '17 at 22:51
  • Si quieres editar los datos de la tabla en la propia GUI y que se adapte automáticamente agrega `self.lista.horizontalHeader().setResizeMode(QtGui.QHeaderView.ResizeToContents)` a tu `setupUI` – FJSevilla Oct 02 '17 at 23:03
  • Excelentismo, exactamente asi es que lo deseaba. seguiré indagando y aprendiendoy gracias por tu ayuda y concejos.Una pregunta mas, en cuanto tiempo promedio se aprende medianamente bien python? – Marco Salazar Oct 03 '17 at 00:21
  • Hola estoy por empezar en Python y quiero ir organizando un programa que quiero hacer. pero me ha saltado una duda: Que es lo mas recomendable? hacer la aplicación con un Qmainwindow padre y que desde alli se llamen Qdialog, o todas pueden ser Qmainwindow? – Marco Salazar Oct 03 '17 at 00:33
  • @MarcoSalazar Python es un lenguaje que si por algo se caracteriza es por la facilidad de aprendizaje. Tardar más o menos depende en gran medida de los conocimientos previos sobre lógica, dominio de la programación orientada a objetos, etc. Si se viene de otros lenguajes con OOP se puede aprender en un par de semanas o menos bien. Si hay que aprender a programar llevara mas tiempo comprender conceptos como las clases, objetos, técnicas de paralelismo/concurrencia, etc. Si le dedicas algo de tiempo puedes tener un buen nivel en un mes partiendo desde 0 . – FJSevilla Oct 03 '17 at 08:34
  • Claro que nunca se termina de aprender a programar, . Ten en cuenta que a esto tienes que añadirle pyQt. Qt es una biblioteca realmente buena y potente, dominarla cuesta lo suyo y a veces ayuda saber algo de C++ (lenjuaje que se usa en Qt). En cuanto a tu segunda duda, no hay nada que impida usar varias QMainWindow en una misma aplición (es un widget mas con barras de menú, herramientas y estado), no obstante por cuestiones de diseño se usa una sola a no ser en aplicaciones que crean nuevas instancias de si misma (por ejemplo cuando en un navegador abres una pagina en una nueva ventana). – FJSevilla Oct 03 '17 at 08:43