Le tri de pyqt tablewidget
Comment puis-je trier un coloumn en pyqt par le plus grand nombre? Actuellement, j'ai setSortingEnabled(True)
et que seuls les trie par la plupart des nombres (ex. 1,1,1,1,2,2,2,3,3) je veux le faire par le plus grand nombre par exemple (ex. 58,25,15,10). Merci!
Mise À Jour Des Données:
def setmydata(self):
for n, key in enumerate(self.data):
for m, item in enumerate(self.data[key]):
newitem = QtGui.QTableWidgetItem(item)
self.setItem(m, n, newitem)
Code entier:
import sys
from PyQt4.QtGui import QTableWidget
from PyQt4 import QtGui,QtCore,Qt
import MySQLdb as mdb
from functools import partial
import time
class Window(QtGui.QDialog):
process_column_signal = QtCore.pyqtSignal()
def __init__(self,parent=None):
super(Window, self).__init__()
self.layout = QtGui.QVBoxLayout(self)
self.db = mdb.connect('serv','user','pass','db')
self.model = self.db.cursor()
self.initialData = self.get_data_status()
self.table1 = MyTableStatus(self.initialData, 145, 4)
callback = partial(self.process_column,self.table1)
self.process_column_signal.connect(callback)
self.layout.addWidget(self.table1)
self.timer_status = QtCore.QTimer()
self.timer_status.timeout.connect(self.updateAllViews)
self.timer_status.timeout.connect(self.some_method)
# check every half-second
self.timer_status.start(1000*5)
def some_method(self):
self.process_column_signal.emit()
def get_data_status(self):
self.model.execute("""SELECT cpu_juliet,cpu,cpu_julietleft FROM status
WHERE date = (SELECT MAX(date) FROM status)""")
rows_status_cpu = self.model.fetchone()
self.listb1 = ['%s' % rows_status_cpu[0],'%s' % rows_status_cpu[2],'%s' % rows_status_cpu[1],'%s' % rows_status_cpu[1]]#['%s %s' % self.rows_status]
self.model.execute("""SELECT disk_queue_juliet FROM status
WHERE date = (SELECT MAX(date) FROM status)""")
rows_status_disk_queue = self.model.fetchone()
self.lista1 = 'Juliet','Julietleft','Pong','Hulk'
self.listc1 = ['%s' % rows_status_disk_queue,'%s' % rows_status_disk_queue,'%s' % rows_status_disk_queue,'%s' % rows_status_disk_queue ]
if self.listb1[0] >= '80' or self.listc1[0] >= '9':
server_status_Juliet = 'WARNING'
else:
server_status_Juliet = 'Normal'
if self.listb1[1] >= '80' or self.listc1[1] >= '9':
server_status_Julietleft = 'WARNING'
else:
server_status_Julietleft = 'Normal'
if self.listb1[2] >= '80' or self.listc1[2] >= '9':
server_status_Pong = 'WARNING'
else:
server_status_Pong = 'Normal'
if self.listb1[3] >= '80' or self.listc1[3] >= '9':
server_status_Hulk = 'WARNING'
else:
server_status_Hulk = 'Normal'
self.listd1 = ['%s' % server_status_Juliet,'%s' % server_status_Julietleft,'%s' % server_status_Pong,'%s' % server_status_Hulk]
# if server_status_Hulk == "WARNING": #or server_status_Pong == "WARNING" or server_status_Julietleft == "WARNING" or server_status_Juliet == "WARNING":
# self.serverstatus.setStyleSheet("QTabWidget {color: red}")
#status label conditions
self.mystruct1 = {'A':self.lista1, 'B':self.listb1, 'C':self.listc1, 'D':self.listd1}
return self.mystruct1
def updateAllViews(self):
_ = self.get_data_status()
self.updateTable()
def updateTable(self):
self.table1.updateFromDict(self.mystruct1)
def process_column(table1, processCol=1):
colCount = table1.table1.rowCount()
for row in xrange(table1.table1.rowCount()):
for col in xrange(4):
try:
item = table1.table1.item(row, 3)
text = item.text()
if (float(text) >= 20.0 ):
for col in xrange(colCount):
print row
item = table1.table1.item(row,col)
item.setBackground(QtGui.QBrush(QtCore.Qt.yellow))
except:
pass
class MyTableStatus(QTableWidget):
def __init__(self, thestruct, *args):
QTableWidget.__init__(self, *args)
self.setSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Preferred)
self.setHorizontalHeaderLabels(['Server', 'Avg. Disk Queue','CPU Load',"Status"])
self.setSortingEnabled(False)
self.data = {}
self.setmydata()
def updateFromDict(self, aDict):
self.data.clear()
self.data.update(aDict)
self.setmydata()
def setmydata(self):
for n, key in enumerate(self.data):
for m, item in enumerate(self.data[key]):
newitem = QtGui.QTableWidgetItem(item)
self.setItem(m, n, newitem)
def main():
app = QtGui.QApplication(sys.argv)
app.setStyle(QtGui.QStyleFactory.create("plastique"))
main_window = Window()
main_window.repaint()
main_window.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
InformationsquelleAutor | 2012-08-13
Vous devez vous connecter pour publier un commentaire.
Tri alpha-numériquement (donc, en termes de chaînes de caractères, '1', '10', '11', '12', '2', '20', '21', '22', '3', '4' etc. est le bon ordre de tri. Il apparaît que, pour un QTableWidgetItem, si vous utilisez le setData(Qt.EditRole, valeur) de la méthode, l'ordre de tri fonctionne. Selon votre version de Qt (je suppose), vous pourriez avoir à surcharger le moins que la méthode de votre table widget élément.
item
comme indiqué dans la question, dans le Qvariant.setData
, l'argument lui-même doit également sous forme de nombre entier, pas de chaîne. Donc, ce ne sera pas faire le tri de travail :setData(Qt.DisplayRole, '10')
, mais cela va fonctionner :setData(Qt.DisplayRole, 10)
Une alternative à l'utilisation d'une coutume
Item
est d'utiliser unSortFilterProxy
(que vous devriez probablement faire de toute façon). Dans ce cas, vous pouvez définir unlessThan
méthode qui sera utilisée pour le tri. Voici la mienne:Il utilise le
EditRole
pour obtenir les données du tri, de sorte que vous pouvez faire ce que la cartographie pour la convivialité que vous voulez faire dans laDisplayRole
cas. Il a également essaie juste de faire numérique de tri pour les valeurs que peut être convertifloat
, natif de tri autrement. Pas l'approche la plus générale, mais qui semble bien fonctionner pour moi. YMMV.setSourceModel(<original model>)
sur elle et l'utiliser à la place de votre modèle d'origine. Pour le montage vous avez aussi besoin de transmettrestartEditing()
etstopEditing()
appels à votre modèle d'origine. Qui semble bien fonctionner pour moi jusqu'à présent.Une autre solution possible de trier numérique pourrait être, pour ajouter un attribut spécial, et de les comparer en fonction de cette valeur. Mybe qui est un plus java comme moyen.
Une méthode plus simple est de la faire précéder de quelques espaces vides de votre texte numérique. La valeur ascii de ' est inférieur à '0', de sorte qu'il fonctionne comme vous le souhaitez. Voici ce que je fais: