Python PyQt - QTableWidget, JSON и emitSignal, вызывающие пустые ячейки - PullRequest
3 голосов
/ 20 марта 2012

Я использую PyQt для простого приложения, которое читает файл журнала со строками в формате JSON и выводит их в виде таблицы.

Все работает, как и ожидалось, за исключением случаев, когда я пытаюсь испустить сигнал из функции загрузки. Этот сигнал принимается главным окном в слоте, предназначенном для добавления в таблицу новой информации.

Без испускаемого сигнала таблица заполняется полностью и правильно:

Normal view, no signal

Раскомментируя self.emit так, что сигнал испускается, таблица оказывается неполной:

Signal emitted, blank cells

Как видно на первом изображении, таблица НЕ отсортирована, но все поля заполнены. На втором изображении таблица отсортирована, но некоторые поля пусты!

Код, который заполняет таблицу и отправляет сигнал:

#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 по желаемому столбцу, а также обеспечить полное заполнение таблицы?

Ответы [ 2 ]

8 голосов
/ 21 марта 2012

Я думаю, что решение состоит в том, чтобы отключить сортировку при заполнении таблицы путем вызова 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_())
0 голосов
/ 21 марта 2012

Я работал над чем-то похожим, но не настраивал сортировку. Я пробовал оба пути, и оба работали на меня.

Мой список, это список словарей, немного отличающийся от вашего.

Я создал класс 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)

Также попытался использовать, в конце моей функции setsetup:

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

и настройте слот в моем главном окне, в разделе инициализации:

# 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, как рекомендует ответ выше моего.

...