pyqt table sorting in AscendingOrder [duplicate] - python

This question already has answers here:
Sorting numbers in QTableWidget work doesnt right Pyqt5
(1 answer)
Sorting in pyqt tablewidget
(4 answers)
How to customize sorting behaviour in QTableWidget
(2 answers)
Closed 3 days ago.
# Az adatokat tartalmazó txt fájlok nevei és elérési útvonalai
dir_path = r"\\fgmhome4\SZEGED CC\CC írható\ÉD DSO\Scannelés\Patrik\EDDSO" # Az adott mappa elérési útvonala
txt_files = [os.path.join(dir_path, f) for f in os.listdir(dir_path) if f.endswith('.txt')]
# Create the QApplication
app = QApplication([])
app.setWindowIcon(QIcon(r"C:\Users\fodorp3\Downloads\medal.png"))
# Set the application style to the Fusion style
app.setStyle(QStyleFactory.create("Fusion"))
# A táblázat inicializálása
table = QTableWidget()
table.setFixedSize(500, 600)
table.setShowGrid(False)
table.setWindowTitle("Ranglista")
table.setColumnCount(2)
table.setHorizontalHeaderLabels(["Név", "Pontszám"])
table.horizontalHeader().setSectionResizeMode(0, QHeaderView.Stretch)
table.horizontalHeader().setSectionResizeMode(1, QHeaderView.Fixed)
table.setEditTriggers(QTableWidget.NoEditTriggers)
def generate_random_name():
names = ['Laci', 'Jóska', 'Bence', 'Patrik', 'Gandalf', 'Pista', 'Julia', 'Sophie', 'Lucas', 'Oliver', 'Jenőke']
return random.choice(names)
# Az adatok feltöltése a táblázatba
for i, txt_file in enumerate(txt_files):
if os.path.exists(txt_file):
with open(txt_file, "r") as f:
data = f.read().splitlines()
max_line_number = len(data)
table.insertRow(i)
# Icon hozzáadása az első oszlophoz
if i < 1:
icon = QIcon(r"C:\Users\fodorp3\Downloads\Iconshock-Batman-Dark-Night-Batman.ico")
table.setItem(i, 0, QTableWidgetItem(icon, generate_random_name()))
elif i < 2:
icon = QIcon(r"C:\Users\fodorp3\Downloads\medal (1).png")
table.setItem(i, 0, QTableWidgetItem(icon, generate_random_name()))
elif i < 3:
icon = QIcon(r"C:\Users\fodorp3\Downloads\medal (2).png")
table.setItem(i, 0, QTableWidgetItem(icon, generate_random_name()))
else:
table.setItem(i, 0, QTableWidgetItem(generate_random_name()))
table.setItem(i, 1, QTableWidgetItem(str(max_line_number)))
# Set the table style
table.setStyleSheet("""
QTableWidget {
background-color: white;
alternate-background-color: #f2f2f2;
gridline-color: #ccc;
selection-color: white;
selection-background-color: #2f60b3;
}
""")
table.show()
app.exec_()
I want to put the score column in ascending order, the score contains the maximum number of lines in the txt files.
I tried this:
table.sortItems(1,Qt.AscendingOrder)
It's not working
and I also try this:
table.setItem(i, 1, QTableWidgetItem(str(int(max_line_number))))
table.sortItems(1,Qt.AscendingOrder)
Same still not working, the output is:
1
1
1800
1809
2
2
4
I want this output:
1809
1800
4
2
etc.

Related

Adding new fields conditioned and calculate the length using Python QGIS

I am developing a new plugin using python in qgis. I want to get an output with the result of a specific attribute table from another layer already existing in my project => layer "SUPPORT".
That's what I've done so far
my code :
`
tableSUPPORT = QgsVectorLayer('None', 'table_SUPPORT', 'memory')
tableSUPPORT.dataProvider().addAttributes(
[QgsField("Propriétaire", QVariant.String), QgsField("Nb. tronçons", QVariant.Int),
QgsField("Long. (m)", QVariant.Int)])
tableSUPPORT.updateFields()
dicoSUPPORT = {'FT': (0, 0), 'FREE MOBILE': (0, 0), 'PRIVE': (0, 0)}
for sup in coucheSUPPORT.getFeatures():
proprietaire = sup['PROPRIETAI']
if proprietaire in ['FT', 'FREE MOBILE', 'PRIVE']:
dicoSUPPORT[proprietaire] = tuple(map(operator.add, (1, sup['LGR_REEL']), dicoSUPPORT[proprietaire]))
else:
QMessageBox.critical(None, "Problème de support",
"Le support %s possède un propriétaire qui ne fait pas partie de la liste." % str(sup['LIBELLE']))
return None
ligneFT = QgsFeature()
ligneFT.setAttributes(['FT', int(dicoSUPPORT['FT'][0]), int(dicoSUPPORT['FT'][1])])
ligneFREE = QgsFeature()
ligneFREE.setAttributes(['FREE MOBILE', int(dicoSUPPORT['FREE MOBILE'][0]), int(dicoSUPPORT['FREE MOBILE'][1])])
lignePRIVE = QgsFeature()
lignePRIVE.setAttributes(['PRIVE', int(dicoSUPPORT['PRIVE'][0]), int(dicoSUPPORT['PRIVE'][1])])
tableSUPPORT.dataProvider().addFeatures([ligneFT])
tableSUPPORT.dataProvider().addFeatures([ligneFREE])
tableSUPPORT.dataProvider().addFeatures([lignePRIVE])
QgsProject.instance().addMapLayer(tableSUPPORT)
`
and here is the result obtained with this code :
result
but in fact I want this table with these specific rows and columns:
table
This is my support attribute table :
support attribute table
description of each row I want in the result:
`
> row 1 =>FT_SOUT:sum of the length ('LGR_REEL') and count the number if ('PROPRIETAI'='FT' and
> 'TYPE_STRUC'='TRANCHEE')
>
> row 2 =>FT_AERIEN:sum of the length('LGR_REEL') if ('PROPRIETAI'='FT' and
> 'TYPE_STRUC'='AERIEN')
>
> row 3 =>CREATION GC FREE RESEAU:sum of length('LGR_REEL') If
> ('PROPRIETAI'='FREE MOBILE' and 'TYPE_STRUC'='TRANCHEE')
>
> row 4 =>CREATION AERIEN FREE RESEAU:sum of the length ('LGR_REEL') If
> ('PROPRIETAI'='FREE MOBILE' and 'TYPE_STRUC'='AERIEN')
>
> row 5 =>PRIVE :sum of the length ('LGR_REEL') If
> ('PROPRIETAI'='PRIVE')
`
i have been asking this at stackexchang but no one answers me
this is my question
https://gis.stackexchange.com/questions/448698/adding-new-fields-conditioned-and-calculate-the-length-using-python-qgis

How to to save one document based on an if statement in Python?

I am trying to save a document based on a if statement.
Here I am creating radiobuttons:
info = ["Option 1", "Option 2", "Option 3"]
vars = []
for idx,i in enumerate(info):
var = IntVar(value=0)
vars.append(var)
lblOption = Label(main,text=i)
btnYes = Radiobutton(main, text="Yes", variable=var, value=2)
btnNo = Radiobutton(main, text="No", variable=var, value=1)
btnNa = Radiobutton(main, text="N/A", variable=var,value=0)
lblOption.grid(column=4,row=idx, sticky = W)
btnYes.grid(column=1,row=idx)
btnNo.grid(column=2,row=idx)
btnNa.grid(column=3,row=idx)
Here I am creating a document
document = Document()
#add table
table = document.add_table(1, 4)
#style table
table.style = 'Table Grid'
#populate header row
heading_cells = table.rows[0].cells
heading_cells[0].text = "Options"
heading_cells[1].text = "Yes"
heading_cells[2].text = "No"
heading_cells[3].text = "N/a"
for idx, item in enumerate(vars):
cells = table.add_row().cells
cells[0].text = info[idx] # gets the option name
val = item.get() #radiobutton value
if val == 2: # checks if yes
cells[1].text = "*"
elif val == 1: # checks if no
cells[2].text = "*"
elif val == 0: # checks if N/A
cells[3].text = "*"
#save doc
document.save("test.docx")
Work behind the scenes:
Out of the 3 radio-button Yes, No, N/a.. Only one can be chosen.
Next, when pressed a button save.. it creates a table in docx, Options is in row 0 appending down along with selected values of Yes, no & N/a.
As an example:
Options Yes No N/a
Option 1 *
Option 2 *
Option 3 *
My Problem:
I can simply press save and it saves the file as test.docx.
Now, I am trying to figure out how to save the file as Failed.docx
The Failed.docx will only be created if one or more out of all the options has a no value selected.
As an example below, this would be saved as Test.docx, because not a single Option has a no value selected:
Options Yes No N/a
Option 1 *
Option 2 *
Option 3 *
An example below, this would be saved as Failed.docx, because no option has been selected for one of the options on the left.
As an example:
Options Yes No N/a
Option 1 *
Option 2 *
Option 3 *
Here is what I have tried so far:
for x in cells[2].text:
if "*" in x:
print("True")
else:
print("False")
This detects * within the cell[2] (This is row 2 linked to No value).
And if a 'no' value has been selected it prints out true but also prints out false
As an example:
Options Yes No N/a
Option 1 *
Option 2 *
Option 3 *
Output of the for loop :
False
True
False
But if it detects False and True both files will be saved. I am totally confused where to go from here..
Question: The 'Failed.docx' will only be created if one or more out of all the options has a no value selected.
This can be rephrased to:
if any option has NO
You have build a list of Boolean from the condition value == NO,
like [False, True, False]
Built-in - any
any(iterable)
Return True if any element of the iterable is true. If the iterable is empty, return False.
YES = 2; NO = 1; NA = 0
print(vars)
if any([v.get() == NO for v in vars]):
print('Failed.docx')
else:
print('test.docx')
Output:
[2, 0, 2]
test.docx
[2, 1, 2]
Failed.docx
Try the following:
for x in cells[2].text:
if "*" in x:
print("Failed.docx")
elif "*" not in x:
print("Test.docx")
this checks if any "*" is inside your no row, if it exists save as Failed.docx if not save as Test.docx

Get contents from Qtable which is a child of QTreeWidget

I've created a treewidget with children which contain tables. I'd like to acces the contents of the QtableWidget but I cannot find how to do this?
The treewidget looks like:
I've generated the treewidget like:
software = QTreeWidgetItem(['Software'])
hardware = QTreeWidgetItem(['Hardware'])
beide = QTreeWidgetItem(['Beide'])
andere = QTreeWidgetItem(['Andere'])
i = 0
for key, value in sorted(data.items()):
if value['Subtype'] == 'Software':
sub = software
if value['Subtype'] == 'Hardware':
sub = hardware
if value['Subtype'] == 'Beide':
sub = beide
if value['Subtype'] == 'Andere':
sub = andere
l1 = QTreeWidgetItem(sub)
if value['Privacy'] == 'Voorzichtig':
l1.setBackgroundColor(0, QColor('orange'))
if value['Privacy'] == 'Vertrouwelijk':
l1.setBackgroundColor(0, QColor('red'))
l1.setTextColor(0, QColor('white'))
l1.setText(0, value['sDesc'])
self.treeMainDisplay.addTopLevelItem(l1)
l1_child = QTreeWidgetItem(l1)
self.item_table = QTableWidget()
self.item_table.verticalHeader().setVisible(False)
self.item_table.horizontalHeader().setVisible(False)
self.item_table.setColumnCount(5)
self.item_table.setRowCount(5)
c1_item = QTableWidgetItem("%s" % value['sDesc'].encode('utf-8'))
self.item_table.setItem(0, 0, c1_item)
c2_item = QTableWidgetItem("%s" % value['Type'].encode('utf-8'))
self.item_table.setItem(1,0, c2_item)
qt_child = self.treeMainDisplay.setItemWidget(l1_child, 0, self.item_table)
self.treeMainDisplay.addTopLevelItem(software)
self.treeMainDisplay.addTopLevelItem(hardware)
self.treeMainDisplay.addTopLevelItem(beide)
self.treeMainDisplay.addTopLevelItem(andere)
I'm iterating over the treewidgetitems but don't know how to access the table contents:
def testItems(self):
iterator = QTreeWidgetItemIterator(self.treeMainDisplay)
while iterator.value():
item = iterator.value()
if not item.text(0):
#Get Table Object?
# item.item(0,0).text()
else:
print item.text(0)
iterator += 1
It seems I can't get acces to the QTableWidget object, I only get the QTreeWidgetItem object.
All feedback is highly appreciated!
The item widgets must be access via the tree-widget using the itemWidget method:
def testItems(self):
iterator = QTreeWidgetItemIterator(self.treeMainDisplay)
while iterator.value():
item = iterator.value()
if not item.text(0):
# Get Table Object
table = self.treeMainDisplay.itemWidget(item, 0)
else:
print item.text(0)
iterator += 1

Update a HTML table in Python

I am a novice coder. I have a HTML table that looks like this and is dynamically created by a python script.
A B C D E F
G 1 1 0 0 1 1
H 1 0 1 2 4 5
Here is the code that generates this table:
f.write("<center><table align = 'center' border=\"1\" width=\"800\" height=\"40\"><tr><td align = 'center'><h3><b>Compared TaskLogs</h3></td><td align = 'center'><h3><b>Total</h3></td><td align = 'center'><h3><b>Passed</h3></td><td colspan = '3' align = 'center'><h3><b>Bug</h3></td><td align = 'center' colspan ='3'><h3><b>Script</h3></td><td align = 'center' colspan = '3'><h3><b>Setup</h3></td></tr></b>");
f.write("<tr><td></td><td></td><td></td>")
f.write("<td align = 'center'><h5><b>Known</b></h4></td><td align = 'center'><h5><b>Unknown</b></h4></td><td align = 'center'><h5><b>Total</b></h5>")
f.write("<td align = 'center'><h5><b>Known</b></h4></td><td align = 'center'><h5><b>Unknown</b></h4></td><td align = 'center'><h5><b>Total</b></h5>")
f.write("<td align = 'center'><h5><b>Known</b></h4></td><td align = 'center'><h5><b>Unknown</b></h4></td><td align = 'center'><h5><b>Total</b></h5>")
f.write("</tr>")
if 'text' in s:
counter_pass=0;
counter_kbug=0;
counter_kscr=0;
counter_kset=0;
counter_uscr=0;
counter_ubug=0;
counter_uset=0;
totbug = 0;
totscr = 0;
totset = 0;
tottc=0;
for key, value in tlogs.items():
print"entering loop: for key, value in tlogs.items(): VALUE:",value
print "ITEM:",s
if (value==s):
value1=tcstatus[key]
print "VALUE--", value1
if value1=="p":
counter_pass=counter_pass+1;
if value1=="kbug":
counter_kbug=counter_kbug+1;
if value1=="kscr":
counter_kscr=counter_kscr+1;
if value1=="kset":
counter_kset=counter_kset+1;
if value1=="ubug":
counter_ubug=counter_ubug+1;
if value1=="uscr":
counter_uscr=counter_uscr+1;
if value1=="uset":
counter_uset=counter_uset+1;
totbug = counter_kbug+counter_ubug
totscr = counter_kscr+counter_uscr
totset = counter_kset+counter_uset
tot = counter_pass+totbug+totscr+totset
f.write("<tr><td height=\"30\">"+str(tot)+"</td><td height=\"30\">"+str(counter_pass)+"</td><td height=\"30\">"+str(counter_kbug)+"</td><td>"+str(counter_ubug)+"</td><td height=\"30\">"+str(totbug)+"</td><td height=\"30\">"+str(counter_kscr)+"</td><td height=\"30\">"+str(counter_uscr)+"</td><td height=\"30\">"+str(totscr)+"</td><td height=\"30\">"+str(counter_kset)+"</td><td height=\"30\">"+str(counter_uset)+"</td><td height=\"30\">"+str(totset)+"</td></tr></center><br>");
f.write("</table></center></body>")
I have another text file that looks like this:
G,A
H,E
Now I need to update the table entry in the Gth row and Ath column by 1 and Hth row and Eth column by 1.
All this is done in python. Could someone help me please!

for loop to insert things into a tkinter window

I have Tkinter program that has to add a significant amount of data to the window so I tried to write a for loop to take care of it but since I have to use a string variable for the name of the object that Tkinter is running .insert() on the object. I didn't explain it very well here is the method
def fillWindow(self):
global fileDirectory
location = os.path.join(fileDirectory, family + '.txt')
file = open(location, 'r')
ordersDict = {}
for line in file:
(key, value) = line.split(':', 1)
ordersDict[key] = value
for key in ordersDict:
ordersDict[key] = ordersDict[key][:-2]
for item in ordersDict:
if item[0] == '#':
if item[1] == 'o':
name = 'ordered%s' %item[2:]
right here is the problem line because I have the variable that matches the name of the entry object already created but 'name' is actually a string variable so it gives me the error "AttributeError: 'str' object has no attribute 'insert'"
name.insert(0,ordersDict[item])
here is the entire class. It makes a Tkinter window and fills it with a sort of shipping screen so all the entries are for how many orders of a certain thing are needed. I'm also very new so I know that I do things the long way a lot.
class EditShippingWindow(Tkinter.Toplevel):
def __init__(self, student):
Tkinter.Toplevel.__init__(self)
self.title('Orders')
family = student
## Window Filling
ageGroupLabel = Tkinter.Label(self,text='Age Group')
ageGroupLabel.grid(row=0,column=0)
itemColumnLabel = Tkinter.Label(self,text='Item')
itemColumnLabel.grid(row=0, column=1)
costColumnLabel = Tkinter.Label(self,text='Cost')
costColumnLabel.grid(row=0, column=2)
orderedColumnLabel = Tkinter.Label(self,text='Ordered')
orderedColumnLabel.grid(row=0, column=3)
paidColumnLabel = Tkinter.Label(self,text='Paid')
paidColumnLabel.grid(row=0, column=4)
receivedColumnLabel = Tkinter.Label(self,text='Received')
receivedColumnLabel.grid(row=0, column=5)
#Item Filling
column1list = ['T-Shirt (2T):$9.00', 'T-Shirt (3T):$9.00', 'T-Shirt (4T):$9.00',
'Praise Music CD:$10.00', ':', 'Vest L(Size 6):$10.00', 'Vest XL(Size 8):$10.00',
'Hand Book (KJ/NIV):$8.75', 'Handbook Bag:$6.00', 'Memory CD (KJ/NIV):$10.00',
':', 'Vest L(size 10):$10.00', 'Vest XL(Size 12):$10.00', 'Hand Glider (KJ/NIV/NKJ):$10.00',
'Wing Runner (KJ/NIV/NKJ):$10.00', 'Sky Stormer (KJ/NIV/NKJ):$10.00', 'Handbook Bag:$5.00',
'Memory CD (S/H/C):$10.00', 'Hand Glider Freq. Flyer:$8.00', 'Wing Runner Freq. Flyer:$8.00',
'Sky Stormer Handbook:$8.00' , ':', 'Uniform T-Shirt Size (10/12/14):$13.00',
'Uniform T-Shirt Size(10/12/14):$13.00', 'Uniform T-Shirt(Adult S / M / L / XL):$13.00',
'3rd & 4th Gr. Book 1 (KJ / NIV / NKJ):$8.75', '3rd & 4th Gr. Book 2 (KJ / NIV / NKJ):$8.75',
'4th & 5th Gr. Book 1 (KJ / NIV / NKJ):$8.75', '4th & 5th Gr. Book 2 (KJ / NIV / NKJ):$8.75',
'Memory CD 3rd & 4th Gr. Book (1/2):$10.00', 'Drawstring Backpack:$5.50']
column1num = 1
for item in column1list:
num = str(column1num)
(title, price) = item.split(':')
objectName1 = 'column1row' + num
objectName1 = Tkinter.Label(self,text=title)
objectName1.grid(row=column1num, column=1)
objectName2 = 'column1row' + num
objectName2 = Tkinter.Label(self,text=price)
objectName2.grid(row=column1num, column=2)
column1num += 1
#Ordered Paid Recieved Filler
for i in range(32):
if i == 11 or i == 22 or i == 0 or i == 5:
pass
else:
width = 10
# First Column
title1 = 'ordered' + str(i)
self.title1 = Tkinter.Entry(self,width=width)
self.title1.grid(row=i,column=3)
#self.title1.insert(0, title1)
#Second
title2 = 'paid' + str(i)
self.title2 = Tkinter.Entry(self,width=width)
self.title2.grid(row=i,column=4)
#self.title2.insert(0, title2)
#Third
title3 = 'received' + str(i)
self.title3 = Tkinter.Entry(self,width=width)
self.title3.grid(row=i,column=5)
#self.title3.insert(0, title3)
## Methods
def fillWindow(self):
global fileDirectory
location = os.path.join(fileDirectory, family + '.txt')
file = open(location, 'r')
ordersDict = {}
for line in file:
(key, value) = line.split(':', 1)
ordersDict[key] = value
for key in ordersDict:
ordersDict[key] = ordersDict[key][:-2]
for item in ordersDict:
if item[0] == '#':
if item[1] == 'o':
self.name = 'ordered%s' %item[2:]
self.name.insert(0,ordersDict[item])
fillWindow(self)
It looks like you have a conceptual error there: inside this method, the variable "name" does not exist up to the last line on the first listing. Then it is created, and points to an ordinary Python string -- if you are using a "name" variable elsewhere on your class that variable does not exist inside this method.
For an easy fix of your existing code, try calling the variable as "self.name" instead of just name where it is created, and on your last line in this method use:
self.name.insert(0,ordersDict[item]) instead.
The self. prefix will turn your variable into an instance variable, which is shared across methods on the same instance of the class.
On a side note, you don' t need even the dictionary much less three consecutive for loops on this method, just insert the relevant values you extract from "line" in your text variable.

Categories

Resources