Looping over grid to get label and entry text values in tkinter - python

I have created a window using tkinter, this window contains a grid of Labels and Entries. In the Entries I have edited some text that I want to save back to the source.
Everything I'm reading so far says that I need to create a separate list and save each entry text variable in the list.
But isn't there a better way to get the values directly from the controls themselves? I know I can loop over mywindow.winfo_children or mywindow.children. So if I can do this, then I should be able to get the text values directly, no?
I just don't know which property to get the value from.
Any ideas out there?

This is the answer.
for child in context.grid_slaves():
if(type(child) is label):
print (child['text'])
if(type(child) is entry):
print(child.get())
I can also find out where I am in the grid like this: child.grid_info() and so I can synch back to the source.

Just to elaborate on the answer.
Loop through the window grid items using the grid_slaves method.
Get the row and column using the widget's grid_info method:
for child in window.grid_slaves():
g_info = child.grid_info()
if type(child) is Button:
row = g_info['row']
col = g_info['column']
text = child['text']
print(row, col, text)

Related

Tkinter, How do i save the entry/dropdown selection to a str variable in my script

I have searched for answers to this question and always get sent back to printing the selection with print(var.get()).
I don't want to print the selection, but to store it in a variable that I can then use in my code.
For more context, I'm making a simple gui to filter data frames. There are a bunch of dropdown menus from which the user selects specific features. I then want to get all of those features to filter down my data frame to a single entry.
The code snippet below shows what I'm trying, but I don't know how to get the data frame that the function filter_df returns (the data frame df is defined before).
I'd also need to use the value of each previous dropdown menu to remove all the impossible feature values (as in, no entry has both the previous value and the one I select after).
Is any of this possible, or are there elements I'm going to have to find a way around ?
I thank any and all answers in advance, this website is what makes the (or at least my) coding world go round.
app = tk.Tk()
app.geometry('100x200')
detail_app_str = tk.StringVar(app)
detail_app_str.set('Select Scope')
detail_dropedown = tk.OptionMenu(app, detail_app_str, *feature_values)
detail_dropedown.config(width=90, font=('Helvetica', 12))
detail_dropedown.pack(side="top")
def filter_df(*args):
filtered_df = df[(df['A'] == int(detail_app_str.get()))]
return filtered_df
detail_app_str.trace_add("write", filter_df)

How to clear table widget pyqt5 in order to add new content

I've been trying to figure out how to clear tableWidget so i can add new content. The snippet below shows the widget and how the information is added. However, anytime i refresh it, instead of clearing the screen it rather add more information.
Any help will be appreciated.
Thanks
def addNewContent(results):
header = self.tableWidget.horizontalHeader()
self.tableWidget.clearContents()
header.setSectionResizeMode(QtWidgets.QHeaderView.ResizeToContents)
numrows = len(results)
numcols = len(results[0])
self.tableWidget.setRowCount(numrows)
self.tableWidget.setColumnCount(numcols)
for row in range(numrows):
for column in range(numcols):
self.tableWidget.setItem(row, column, QTableWidgetItem((str(results[row][column]))))
addNewContent(results)
I've searched a lot for this problem the only solution that I came up with, was to call model.clear() and then setting the header labels once again
I think problem is in the variable result i believe its a list so all what you have to do is reinitialize it then append it with the new values somewhere in your code

wrap text in an entry widget in tkinter

I want to create an interactive text box in a tkinter GUI, the text box should get the text to wrap to the next line after the length of 30 characters, like it would do using the wraplength=30 attribute in a label widget. I am trying to get it to work using an Entry widget, this is what I am aiming for (apart from the wraplength attribute needs to be changed to something that works in an Entry widget:
ent = Entry(root, width=30, wraplength=30)
I also need to be able to make the Entry widget taller than one line, is there a way i can do that, for example making it vertically fill a frame (similarly to expand=True making it horizontally fill a frame).
Thank you!
I believe that Entry widgets are single line only, you may want to try Text widget
https://tkdocs.com/tutorial/morewidgets.html#text
The entry widget doesn't support wrapping. If you want to have multiple lines -- even if it's one long line that's wrapped -- you'll need to use either a Text, Label, or Message widget. Only the Text widget supports user input, the other two are strictly for display.
As for making the entry widget taller, you can do that with a geometry manager. For example, you can use the sticky option of grid or the fill and expand options of pack. This will make the widget taller, but the text will still just appear as a single line.
but text can't use (show="")

Two lines of text in a single grid row

Does anybody know if it's possible to put two lines of text in a single row using grid in TKinter?
If I make the font small enough, can I distribute the text in two lines?
>>> import Tkinter as tk
>>> root = tk.Tk()
>>> tk.Label(master=root, text="Line1\nLine2").grid(row=0)
>>> root.mainloop()
Worked for me and produced an image like this:
You can put multiple items in one cell but it is highly unusual, may have surprising behavior, and there are better ways to accomplish the same effect.
For example, the grid is invisible so you can have as many rows as you want to achieve any look you can imagine. Also, the definition of "item" is pretty loose -- you can create a frame, and in that frame put two labels, and that frame can go in a single row using grid to give the appearance of two lines of text in a single grid row. You can also use a text widget which lets you put as many lines of text that you want.

How do I hide all columns in a treelistitem?

I'm using the HyperTreeList to display a list of items with the name in the first column, and a "Remove" button in the second column. I wrote a function to filter what is displayed in the tree by some text in a TextCtrl. To hide the TreeListItems, I'm doing this:
treelist.HideItem(branch, True)
where treelist is a HyperTreeList and branch is a TreeListItem. The first column hides just fine, but none of the buttons in the second column hide. How do I get all columns in a TreeListItem to hide?
According to the docs, this should work:
treelist.SetColumnShown(column_index, False)
but this will hide that column for everything. If I understand what you're saying, the row you are trying to hide doesn't actually disappear, just the value of the first column. In that case, you might have to refresh the widget with treelist.Update() to get the rest of the row to disappear.

Categories