1

次の列を持つ QTableWidget があります。

    Username    Password     URL       Status
   +----------+-----------+---------+---------+
   |  user1   |  passwd1  | url.com |   OK    |
   |  user2   |  passwd2  | url.com |   FAIL  |
   +----------+-----------+---------+---------+

私のアプリケーションのワーカーQThreadでは、テーブルに表示されたデータを含むシグナルが発行されます。ただし、このデータは後で更新する必要があります (特に [ステータス] 列)。

たとえば、2行目だけを更新できるようにしたいと思います。これまでのところ、テーブル内のすべての行をループしてから、一意のフィールド (ユーザー名など) をソフトウェアから送信されたデータと一致させようとしました。したがって、行 2 のステータスを「FAIL」から「RETRY」に更新する必要がある場合、GUI スレッドに送信されるシグナルには、ユーザー名とステータス文字列が含まれます。次に、2 つの文字列 (信号からの文字列、つまり QThread と現在テーブルにある文字列) を比較し、一致する場合はテーブルを更新します。うまくいけば、これは理にかなっています。

問題は、これが実行可能な解決策であるかどうか疑問に思っていますか? 他にある?QTableWidget に別の「隠し」列を追加することを検討しました。これには、すべての QThread によって生成されたランダムな文字列が含まれ、更新されます。しかし、原則は同じです。

誰かが私に何か指針を与えることができますか?

編集: リクエストごとにコードを追加:

これは私のGUIスレッドコードです(検索と更新部分):

def writeToMainTable(self, param):

    username = param['username']
    statusText = param['statusText']

    for i in xrange(self.mainTable.currentRowCount()):
        if username == self.mainTable.item(i, 0).text():
            found = True
            activerow = i    

    if found:
        if statusText is not None: self.mainTable.setItem(activerow, 3, QTableWidgetItem(statusText))

QThread には次のようなものがあります。

def sendToTable(self, param): #param is a dict here as well
    self.mainsig.emit(param)
4

2 に答える 2

0

QThread各行を更新するために異なるを使用しているように見えるのでQSignalMapper、次のようなa を使用できます。

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

import time, random

from PyQt4 import QtGui, QtCore

class MyThread(QtCore.QThread):
    statusChanged = QtCore.pyqtSignal()

    def __init__(self, parent=None):
        super(MyThread, self).__init__(parent)
        self.status = None

    def run(self):
        time.sleep(3)
        self.status = True if not self.status else False
        self.statusChanged.emit()


class MyWindow(QtGui.QWidget):
    def __init__(self, parent=None):
        super(MyWindow, self).__init__(parent)

        self.tableWidget = QtGui.QTableWidget(self)
        self.tableWidget.setRowCount(2)
        self.tableWidget.setColumnCount(4)
        self.tableWidget.horizontalHeader().setResizeMode(QtGui.QHeaderView.Stretch)

        self.signalMapper = QtCore.QSignalMapper(self)  
        self.signalMapper.mapped.connect(self.on_signalMapper_mapped)  

        for row in range(2):
            status = random.getrandbits(1)
            state  = "Ok" if status else "Failed"
            thread = MyThread(self)
            thread.status = status

            self.signalMapper.setMapping(thread, row)

            thread.statusChanged.connect(self.signalMapper.map)
            thread.start()

            values = ["user", "passwd", "url.com", state]
            for column, value in enumerate(values):
                item = QtGui.QTableWidgetItem()
                item.setText("{0}: {1}".format(row, value))

                self.tableWidget.setItem(row, column, item)

        self.gridLayout = QtGui.QGridLayout(self)
        self.gridLayout.addWidget(self.tableWidget, 0, 0)

    @QtCore.pyqtSlot(int)
    def on_signalMapper_mapped(self, number):
        state  = "Ok" if self.signalMapper.mapping(number).status else "Failed"
        item   = self.tableWidget.item(number, 3)
        item.setText("{0}: {1}".format(number, state))

if __name__ == "__main__":
    import sys

    app = QtGui.QApplication(sys.argv)
    app.setApplicationName('MyWindow')

    main = MyWindow()
    main.resize(666, 111)
    main.show()

    sys.exit(app.exec_())
于 2013-02-03T01:23:45.427 に答える
0

あなたが何を望んでいるのか正確にはわかりません。Qtにループをさせたいと思いますか?もしそうなら、ここに方法があります。お役に立てれば。

import sys

from PySide.QtCore import *
from PySide.QtGui import *

class Main(QWidget):

    def __init__(self):
        super(Main, self).__init__()

        self.table = Table(self)
        self.change = QPushButton('Change')

        layout = QHBoxLayout(self)

        layout.addWidget(self.table)
        layout.addWidget(self.change)

        self.change.clicked.connect(self.table.updateCell)

class Table(QTableWidget):

    def __init__(self, parent=None):
        super(Table, self).__init__(2, 2, parent)
        self.setItem(1, 0, QTableWidgetItem('test'))
        self.setItem(1, 1, QTableWidgetItem('False'))

    def updateCell(self):

        item, = self.findItems('test', Qt.MatchExactly)
        new = repr(not eval(self.item(item.row(), 1).text()))
        self.item(row, 1).setText(new)


app = QApplication([])  
main = Main()
main.show()
app.exec_()
于 2013-02-01T21:25:15.010 に答える