Edit the cell's content of a QTableWidget in the code - python

In my code, I've created a QTableWidget with 50 columns and 2 rows.
By executing a function, Python put in cells list's elements that I've created before. But, I don't know how to modify these cells.
For example, I want to get the current data of a cell at (x,y) and add an integer. So I've tried :
content = int(self.ui.table.item(X, Y).text()) #I've just strings in my cells
self.ui.table.item(X, Y).setText(str(content + 1)
But that part of code, don't work.
I've tried too :
a=self.ui.table.item(X,Y)
print(a.data(0).toString())
But Python return me :
'NoneType' object has no attribute 'data'

Try this,hope this will work:
val = 21 # integer value
row = X # this is your row number
self.ui.table.insertRow(row) # here you decide in which row
item = QTableWidgetItem(str(val)) # create a new Item
self.ui.table.setItem(row,Y, item)
This will override the value at X,Y index of QTableWidget cell.

if you used QtDesigner to create the user interface, particularly the tables, is probably that you have a instances problem, Qtdesigner create the table (QTablewiget) but does not create cells (QTableWidgetItem) inside the table, these is the reason that when you try to get the item X, Y you got a "noneType" object, I know its sound crazy there is 3 ways to solve these:
1st : you can create the individual items as #zeb show it
2do : fill the cell on QtDesigner with a value, with this Qtdesigner create the tables items
3th : you can crare each element you need to use on the setupUi funciton as :
item = self.table.item(X,Y)
item.setText(_translate("MainWindow", " "))

Related

Is there a way to fill in the gaps of missing/empty data for each of the printed rows to ensure all data is structured similarly?

Please see the below code that I am using to scrape content from a dynamically generated page and then placing into a CSV. The problem I am running into now is that each "row" could potentially be missing certain elements that I would like to insert as "blank" or some other placeholder so that all of the rows are correctly located under the correct column header when I view this in excel.
with open(filename, 'w', newline='') as csvfile:
csvwriter = csv.writer(csvfile)
for heading in All_Heading:
driver.execute_script("return arguments[0].scrollIntoView(true);", heading)
#print("------------- " + heading.text + " -------------")
ChildElement = heading.find_elements_by_xpath("./../div/div")
for child in ChildElement:
driver.execute_script("return arguments[0].scrollIntoView(true);", child)
#print(heading.text)
#print(child.text)
row = [heading.text, *child.text.split("\n")] # You can also use a tuple here
print (row)
csvwriter.writerow(row)
Is it possible to place the sort of logic I am after in the writer statement or will I need to specifically go after each element I am after to know if it is empty or not? In the end I want each row to contain the same number of elements, even if it means some of them are blank or filler text as this will keep the overall struture of the data intact.
Examples of the output below:
As you can see some elements were empty and as such the following elements end up out of line/in the wrong column. (11,12,13,26)
On the same note, is it possible to know extra information about the element I am dealing with in the loop that prints the row? If I knew the class I could then know if its the title, price, weight, brand or so on.
Thank you!
It’s not possible to identify what’s missing from the text itself, at least not reliably since you’d have to search for certain substrings to identify the fields. However if you do have all these values in separate elements under child, you can associate each element with its field in two ways assuming there is a class uniquely identifying each field:
You can go through all the children using WebElement. find_elements(By.XPATH, ".//*"), record what fields are present using someClass in WebElement.get_attribute("class"), and later fill in blanks for the missing ones.
You can use WebElement .find_elements() (which searches through WebElement's children) and filter by the known class name i.e. find_elements(by=By.CLASS_NAME, value=className):
# ...
fieldClasses = ["Title", "Price", ...] # These are just example classes
for fieldClass in fieldClasses:
element = child.find_elements(by=By.CLASS_NAME, value=fieldClass)
row.append(element.text if element else "Blank")
# ...
You can simply replace empty spaces with some text, before saving the rows.
Ex:
row = [heading.text, *child.text.split("\n")] # You can also use a tuplehere
print (row)
for i in range(len(row)):
if len(row[i]) < 1:
row[i] = "Filler"
csvwriter.writerow(row)

How to iterate over different ids levels using weakref in kivy

I have this sequence of ids.
self.ids.cuarta_pantalla.ids.container.ids.pre_1.ids.Si
In this case, container has 70 different ids [from pre_1 until pre_70] and each pre_(x) has three different ids [Si, MasMenos, No] that correspondes to a group of CheckBoxes.
If I want to know the state of a single checkbox using its atribute value, I'm forced to write all the statement like this.
self.ids.cuarta_pantalla.ids.container.ids.pre_1.ids.Si.value.
So, How can I iterate over the ids?
I've tried using square brackets self.ids.cuarta_pantalla.ids.container.ids['pre_1'] but it returns something with which I can't call any method.
Print with Square brackets: <weakref at 0x125F7118; to 'BoxLayout' at 0x125F30D0>
Print with dot notation: <kivy.uix.boxlayout.BoxLayout object at 0x125F30D0>
This is the way I've created the objects:
for idx in range(70):
BoxContainer = BoxLayout()
# Repeat this two more times with MasMenos and No
check1 = CheckBox(group= f"p_{idx+1}")
BoxContainer.add_widget(check1)
BoxContainer.ids['Si'] = weakref.ref(check1)
#Adding the BoxContainer with CheckBoxes to the container
self.ids.cuarta_pantalla.ids.container.add_widget(BoxContainer)
self.ids.cuarta_pantalla.ids.container.ids[f'pre_{idx+1}'] = weakref.ref(BoxContainer)
There is no need to use weakref, every time that add_widget is used, an Observable List called children into the object in which was added the other one will contain the reference of that added object.
For example:
IDlist = self.ids.cuarta_pantalla.ids.container.children
The variable IDlist can be iterated to get each reference where you can call any method of that particular object

How to insert value in existing list in a specific index by moving the existing value to next index using python

I have list like below.
test = ['firstvalue', 'thirdvalue']
I want to insert the some values to the list.
secondvalue at index 1 and fourthvalue at index 3
so the output list looks like below
test = ['firstvalue', 'secondvalue', 'thirdvalue', 'fourthvalue']
I tried the below way but it doesn't work for me
print test.insert(1, "secondvalue")
Is there any alternate way to do this?
The insert function does not return a value, but rather modifies the array used on it. Here's an example:
test = ['firstvalue', 'thirdvalue']
test.insert(1, "secondvalue")
print test

Fill dictionary with dynamic values

I got a probem I am not able to solve for quiet some time and maybe someone of you can help me.
Because it is a more easy code and it's clear what it is good for, I would like to start wit the code:
#Create empty dictionary
lit_dict = {}
#List with different material names
mat_category_list = ['X', 'Y', 'Z', 'Default']
#Fill lit_dict with lists called e.g "lit_names_X" for every material
for mat in mat_category_list:
lit_dict['lit_name_%s'%mat.lower()] = [('Choose Manually','Choose Manually','Choose the value using the button below')]
So far the code is working fine. I get a dictionary (lit_dict) with a key called lit_name_A for every material A stored in the list mat_category_list. Furthermore, every key has the value ('Choose Manually','Choose Manually','Choose the value using the button below'). That's exactly what I want. Every value has to be a tuple.
Now we are getting to the problem. I have a dictionary called mat_properties_A for every material A. These dictionaries look like that e.g.:
mat_properties_A= {'A.Geramy,2000':Material_Property(13700.0,0.38,reference='A.Geramy,2000',mat='Bone')
I now want a loop which adds for every material A the names of every key of the mat_properties_A dictionary as a tuple to my lit_dict to the right list lit_name_A
The loop should look like that:
for mat in mat_category_list:
for lit in mat_properties_A.keys():
lit_dict['lit_value_%s'%mat.lower()] += [tuple([lit]*3)]
My problem is now that the A in the second row above has to be dynamic that means it has to change with the mat loop. I tried to solve that probelm with a setattr() or so but it does not work.
Does anyone has an idea how to solve that problem?
Edit1:
To clearify more what I want to achieve:
I am working with Blender. There I have 2 Dropdown menus. One where I can choose the material I want (e.g. X) and then a second Dorpdown menu where then (based on the choosen material in the first drowpdon) I can choose the corresponding names of literature.
So for example:
Dropdown 1: "X"
Dropdown 2: Shows all Names stored in the list lit_name_x
Tha is why I need a lit_name_x for every material in the mat_category_list. The mat_category_list contains all materials which can be selected in Dropdown Menu 1. And because the user is able to create own materials, with own literature, the whole code has to be independent of the names of the materials.
I hope it is more clear what I want as a "Outcome"
for mat in mat_category_list:
keys = eval("mat_properties_%s.keys()" % A)#here, A is the name from mat
for lit in keys:
lit_dict['lit_value_%s'%mat.lower()] += [tuple([lit]*3)]

Gtk.Treeview get current row index in Python

How to get index of current selected row in Gtk.TreeView in Python ?
The other answer is likely more useful in general. However, to answer the actual question posed by the OP, how to get the row index: assuming one row is selected, you can get it with:
index = treeview.get_selection().get_selected_rows()[1][0][0]
You can call gtk.TreeView.get_selection to get the current selection (gtk.TreeSelection). You can then call gtk.TreeSelection.get_selected to get:
a 2-tuple containing a reference to the gtk.TreeModel and a gtk.TreeIter pointing to the currently selected node.
The iter can be used on a gtk.TreeModel (which is obtained by calling gtk.TreeView.get_model. You can then use gtk.TreeModel.get_value to get any of the column values of the node at that position in the tree.
Somewhat late, perhaps not so relevant, but if you have double clicked on the selected row you will get the row index as element of the TreePath tuple, like so
def on_row_activated(self, treeview, path, column):
model = self.treeview.get_model()
tree_iter = model.get_iter(path)
row = path[0]
if tree_iter:
# here you can get the values of the columns

Categories