简体   繁体   中英

How to populate a custom QTableWidget from a slow Sql statement using QThread?

In this case I'm trying to populate a QtableWidget that was modified to load images using class TableWidgetImage

from PyQt4 import QtGui
import sys
class ImageWidget(QtGui.QWidget):
    def __init__(self, imagePath, parent):
        super(ImageWidget, self).__init__(parent)
        self.picture = QtGui.QPixmap(imagePath)
    def paintEvent(self, event):
        painter = QtGui.QPainter(self)
        painter.drawPixmap(0, 0, self.picture)
class TableWidgetImage(QtGui.QTableWidget):
    def setImage(self, row, col, imagePath):
        image = ImageWidget(imagePath, self)
        self.setCellWidget(row, col, image)

The functionality is: I select an ítem from "cbUser" (account) I press "btnCargar" and the "tableSusAmigos" loads ok. My question is focussed in the next step. When I doublé clicked in one row to "tableSusAmigos" It should load the second QTableWidget. It Works. But my problema is when there are many rows. I would like to load using a QThread. I don't how modify a UI QTableWidget control using QThread. This is my other file Python that contains 2 classes:

class Ui_friendForm(QMdiSubWindow):
    def __init__(self):
        QtGui.QMdiSubWindow.__init__(self)
        icon = QtGui.QIcon()
        icon.addPixmap(QtGui.QPixmap(_fromUtf8(":/mmAmistad/mmAmistad.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.setWindowIcon(icon)
        self.resize(878, 637)
        self.cbUser = QtGui.QComboBox(self)
        self.cbUser.setGeometry(QtCore.QRect(20, 70, 211, 22))
        self.cbUser.setObjectName(_fromUtf8("cbUser"))
        self.btnCargar = QtGui.QPushButton(self)
        self.btnCargar.setGeometry(QtCore.QRect(250, 60, 91, 41))
        icon = QtGui.QIcon()
        icon.addPixmap(QtGui.QPixmap(_fromUtf8(":/picLoad/btnLoad.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.btnCargar.setIcon(icon)
        self.btnCargar.setObjectName(_fromUtf8("btnCargar"))
        self.tableSusAmigos = TableWidgetImage(self)
        self.tableSusAmigos.setGeometry(QtCore.QRect(20, 110, 391, 461))
        self.tableSusAmigos.setColumnCount(3)
        self.tableSusAmigos.setObjectName(_fromUtf8("tableSusAmigos"))
        self.tableSusAmigos.setRowCount(0)
        self.tableSusAmigos.verticalHeader().setDefaultSectionSize(50)
        self.tableSusAmigos.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows)
        self.tableSusAmigos.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers)
        self.tableSusAmigos.setSortingEnabled(1)
        item = QtGui.QTableWidgetItem()
        self.tableSusAmigos.setHorizontalHeaderItem(0, item)
        item = QtGui.QTableWidgetItem()
        self.tableSusAmigos.setHorizontalHeaderItem(1, item)
        item = QtGui.QTableWidgetItem()
        self.tableSusAmigos.setHorizontalHeaderItem(2, item)
        self.tableAmigosde = TableWidgetImage(self)
        self.tableAmigosde.setGeometry(QtCore.QRect(470, 110, 381, 461))
        self.tableAmigosde.setColumnCount(3)
        self.tableAmigosde.setObjectName(_fromUtf8("tableAmigosde"))
        self.tableAmigosde.setRowCount(0)
        self.tableAmigosde.verticalHeader().setDefaultSectionSize(50)
        self.tableAmigosde.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows)
        self.tableAmigosde.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers)
        self.tableAmigosde.setSortingEnabled(1)
        item = QtGui.QTableWidgetItem()
        self.tableAmigosde.setHorizontalHeaderItem(0, item)
        item = QtGui.QTableWidgetItem()
        self.tableAmigosde.setHorizontalHeaderItem(1, item)
        item = QtGui.QTableWidgetItem()
        self.tableAmigosde.setHorizontalHeaderItem(2, item)
        self.setWindowTitle(_translate("Form", "Form", None))
        self.btnCargar.setText(_translate("Form", "Cargar", None))
        self.btnCargar.clicked.connect(self.cargarAmigos)
        item = self.tableSusAmigos.horizontalHeaderItem(0)
        item.setText(_translate("Form", "ID", None))
        item = self.tableSusAmigos.horizontalHeaderItem(1)
        item.setText(_translate("Form", "Nombre", None))
        item = self.tableSusAmigos.horizontalHeaderItem(2)
        item.setText(_translate("Form", "Foto", None))
        item = self.tableAmigosde.horizontalHeaderItem(0)
        item.setText(_translate("Form", "ID", None))
        item = self.tableAmigosde.horizontalHeaderItem(1)
        item.setText(_translate("Form", "Nombre", None))
        item = self.tableAmigosde.horizontalHeaderItem(2)
        item.setText(_translate("Form", "Foto", None))
        self.pbCarga = QtGui.QProgressBar(self)
        self.pbCarga.setGeometry(QtCore.QRect(20, 590, 391, 23))
        self.pbCarga.setProperty("value", 24)
        self.pbCarga.setValue(0)
        self.pbCarga.setObjectName(_fromUtf8("pbCarga"))
        self.setWindowTitle(_translate("Form", "List Friends", None))
        self.objDato = DBFacebook()
        self.cargarCombo()
        QtCore.QMetaObject.connectSlotsByName(self)
        self.tableSusAmigos.doubleClicked.connect(self.doubleClicked_table)
        self.thread = TaskThread(self)
        self.thread.started.connect(self.handleTaskUpdated)    
    def cargarCombo(self):
        self.objDato.__enter__()
        for row in self.objDato.SELECT_CUENTA_USER():
            self.cbUser.addItem(str(row[1]),int(row[0]))
        self.objDato.__exit__()
    def doubleClicked_table(self):
        index = self.tableSusAmigos.selectedIndexes()[0]
        self.id_us = int(self.tableSusAmigos.model().data(index).toString())
        self.tableAmigosde.setRowCount(0);
        self.pbCarga.setRange(0,0)
        self.pbCarga.setValue(0)
        self.thread.quit()
        self.thread.start()
    def handleTaskUpdated(self):
        rowIndex = 0
        self.objDato.__enter__()
        for row in self.objDato.SELECT_AMISTADES(self.id_us):
            self.tableAmigosde.insertRow(rowIndex)
            for column in range(0,3):
                if column == 2:
                    self.tableAmigosde.setImage(rowIndex, column, str(row[column]))
                else:
                    newItem = QtGui.QTableWidgetItem(str(row[column]).decode('utf-8'))
                    self.tableAmigosde.setItem(rowIndex,column,newItem)
            rowIndex = rowIndex + 1
        self.objDato.__exit__()
        self.pbCarga.setRange(0,1)
        self.pbCarga.setValue(1)
    def cargarAmigos(self):
        id_us = self.cbUser.itemData(self.cbUser.currentIndex()).toPyObject()
        self.objDato.__enter__()
        rowIndex = 0
        self.tableSusAmigos.setRowCount(0);
        for row in self.objDato.SELECT_AMISTADES(id_us):
            self.tableSusAmigos.insertRow(rowIndex)
            for column in range(0,3):
                if column == 2:
                    self.tableSusAmigos.setImage(rowIndex, column, str(row[column]))
                else:
                    newItem = QtGui.QTableWidgetItem(str(row[column]).decode('utf-8'))
                    self.tableSusAmigos.setItem(rowIndex,column,newItem)
            rowIndex = rowIndex + 1
        self.objDato.__exit__()
class TaskThread(QtCore.QThread):
    def __init__(self,parent):
        QtCore.QThread.__init__(self, parent)
    def run(self):
        self.emit(QtCore.SIGNAL('started'))        
if __name__ == "__main__":
    import sys
    app = QtGui.QApplication(sys.argv)
    ui = Ui_friendForm()
    ui.show()
    sys.exit(app.exec_())

I Attach a picture to my application. Thanks in advance.

在此处输入图片说明

Widgets are only to be accessed from within the main thread. However using slots and signals you have a secure way of interacting with the UI from another thread as long as the default connection type is used.

Check this example I created some time ago (in the wiki there is detailed information on the code). Basically all you need to do is add a slot to wherever your table widget resides. Using the arguments of the slot (which will provide the data for the table item) all you need to do is create the QTableWidgetItem and insert it. As for the signal itself it can be emitted from your worker thread where an object resides that queries your DB and converts the retrieved data to one or multiple table rows, which are then emitted through that signal.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM