【问题标题】:Python PyQt - QTableWidget, JSON, and emitSignal causing blank cellsPython PyQt - QTableWidget、JSON 和 emitSignal 导致空白单元格
【发布时间】:2012-04-05 00:37:07
【问题描述】:

我正在将 PyQt 用于一个简单的应用程序,该应用程序从带有 JSON 格式字符串的日志文件中读取,并将它们很好地输出到表格中。

一切都按预期工作,除非我尝试从“加载”函数发出信号。这个信号被主窗口接收到,在一个槽中,该槽被设计为用新信息重新访问表格。

在没有信号发射的情况下,表格完全正确地填充:

通过取消注释 self.emit 以便发出信号,表格最终不完整:

正如您在第一张图片中看到的那样,表格未排序,但所有字段都已填充。在第二张图片中,表格已排序,但有些字段是空白的!

填充表格并发送信号的代码:

#openLog function does stuff, then populates the table as follows

self.ui.tableWidget.setRowCount(len(entries))
self.ui.tableWidget.verticalHeader().setVisible(False)

for i, row in enumerate(entries):
    for j, col in enumerate(row):
        item = QtGui.QTableWidgetItem(col)
        self.ui.tableWidget.setItem(i, j, item)

#When this is uncommented, the table ends up having a lot of blank cells.
#self.emit(QtCore.SIGNAL("updateSignal"))

接收信号并执行的代码:

#main window class
    #__init__
        self.ui.tableWidget.connect(self,QtCore.SIGNAL("updateSignal"),self.updateTable)

    def updateTable(self):
        self.ui.tableWidget.sortItems(0,QtCore.Qt.DescendingOrder)

程序流程称为:program_init->register_signal。用户打开日志的操作->填充表/发出信号的openLog函数->接收到的信号/处理表

对于这种方法,我使用了信号和插槽,好像我不使用一样,QT/Python 会抛出一堆警告,说明从函数中重绘 GUI/Pixmap 是不安全的。

问题: 如何让 QTableWidget 对我想要的列进行排序,同时确保表格完全填充?

【问题讨论】:

    标签: python pyqt qtablewidget


    【解决方案1】:

    我认为解决方案是在填充表格时通过调用QTableWidget.setSortingEnabled(False) 禁用排序,然后恢复排序。

    示例代码:

    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    import sys
    from PyQt4 import QtCore, QtGui
    
    class MainWindow(QtGui.QWidget):
        updateSignal = QtCore.pyqtSignal()
        def __init__(self, parent=None):
            super(MainWindow, self).__init__(parent)
            self.table_widget = QtGui.QTableWidget()
            self.button = QtGui.QPushButton('Populate')
            self.button.clicked.connect(self.populate)
            layout = QtGui.QVBoxLayout()
            layout.addWidget(self.table_widget)
            layout.addWidget(self.button)
            self.setLayout(layout)
            self.updateSignal.connect(self.update_table)
            self.populate()
    
        def populate(self):
            nrows, ncols = 5, 2
            self.table_widget.setSortingEnabled(False)
            self.table_widget.setRowCount(nrows)
            self.table_widget.setColumnCount(ncols)
            for i in range(nrows):
                for j in range(ncols):
                    item = QtGui.QTableWidgetItem('%s%s' % (i, j))
                    self.table_widget.setItem(i, j, item)
            self.updateSignal.emit()
            self.table_widget.setSortingEnabled(True)
    
        def update_table(self):
            self.table_widget.sortItems(0,QtCore.Qt.DescendingOrder)
    
    
    if __name__ == "__main__":
        app = QtGui.QApplication(sys.argv)
        wnd = MainWindow()
        wnd.resize(640, 480)
        wnd.show()
        sys.exit(app.exec_())
    

    【讨论】:

    • 添加setSortingEnabled 选项,如您的示例所示,实际上确实给了我所期望的行为。 setSortingEnabled(False) 需要在setRowCount() 调用之前和setSortingEnabled(True) 之后 singal.emit()。谢谢。
    • 这个解决方案结束了令人沮丧的日子。谢谢!
    【解决方案2】:

    我一直在做类似的事情,但没有设置排序。我尝试了两种方法,都对我有用。

    我的列表,是一个字典列表,与你的略有不同。

    我创建了一个 tabledialog 类,其中包含我的表格小部件,并且这个函数是从我的主窗口调用的:

    def setuptable(self, alist):
    
        # setup variables
        rows = len(alist)
        cols = len(alist[0])
        keys = ['number', 'name', 'phone', 'address'] # for dictonary order
    
        # setup cols, rows
        self.tableWidget.setRowCount(rows)
        self.tableWidget.setColumnCount(cols)
    
        # insert data
        for row in range(rows):
            for col in range(cols):
                item = QtGui.QTableWidgetItem()
                item.setText(alist[row][keys[col]] or '') # or '' for any None values
                table.setItem(row, col, item)
    
        keys = [item.title() for item in keys]  # capitalize
        self.tableWidget.setHorizontalHeaderLabels(keys) # add header names
        self.tableWidget.horizontalHeader().setDefaultAlignment(QtCore.Qt.AlignLeft) # set alignment
        self.tableWidget.resizeColumnsToContents() # call this after all items have been inserted
    
        self.tableWidget.sortItems(1,QtCore.Qt.AscendingOrder)
    

    还尝试在我的 tablesetup 函数末尾使用:

    self.emit(QtCore.SIGNAL("loadingDone"))
    

    并在我的主窗口的 init 部分设置插槽:

    # setup the dialog
    import dialogtable
    self.tabledialog = dialogtable.dialogtable()
    
    # signal from table dialog
    self.tabledialog.connect(self.tabledialog,QtCore.SIGNAL("loadingDone"),self.tableSort)
    

    以及调用的函数:

    def tableSort(self):
        self.tabledialog.tableWidget.sortItems(1,QtCore.Qt.AscendingOrder)
    

    我的表格小部件设置功能:

        # set table widget attributes
        self.tableWidget.setEditTriggers(QtGui.QAbstractItemView.DoubleClicked) # use NoEditTriggers to disable editing
        self.tableWidget.setAlternatingRowColors(True)
        self.tableWidget.setSelectionMode(QtGui.QAbstractItemView.NoSelection)
        self.tableWidget.verticalHeader().setDefaultSectionSize(18) # tighten up the row size
        self.tableWidget.horizontalHeader().setStretchLastSection(True) # stretch last column to edge
        self.tableWidget.setSortingEnabled(True) # allow sorting
    

    我从不费心将排序设置为 false,正如我上面的答案所建议的那样。

    【讨论】:

      猜你喜欢
      • 2019-02-01
      • 1970-01-01
      • 2017-06-17
      • 1970-01-01
      • 2020-09-09
      • 1970-01-01
      • 2019-02-09
      • 2013-03-15
      • 1970-01-01
      相关资源
      最近更新 更多