populate a list box with .csv items - python-3.x

I have this.
scrollbar = tk.Scrollbar(listbox)
scrollbar.pack(side=RIGHT, fill=Y)
listbox = tk.Listbox(root)
listbox.insert(1,'a')
listbox.pack()
listbox.config(yscrollcommand=scrollbar.set)
scrollbar.config(command=listbox.yview)
with open('testCUR.csv', newline='') as csvfile:
spamreader = csv.reader(csvfile, delimiter=' ', quotechar='|')
for row in spamreader:
print(', '.join(row),'\n')
I was wondering how to correctly populate the listbox with values from a .csv file?
And also why I cannot use the scroll bar correctly?
Once the list box is populated I would like to put the value of the last cell from the selection to a variable for use in a URL string. I havent found any tutorials for this so was looking for help here.
I have tried this.
listbox = tk.Listbox(root, height=1)
listbox.place(x=300,y=75)
with open('testCUR.csv', 'r') as f:
reader = csv.reader(f)
your_list = list(reader)
for item in your_list:
listbox.insert(end, item)
or this inputs only first entry
with open('testCUR.csv', 'r') as f:
reader = csv.reader(f)
your_list = list(reader)
for item in your_list:
listbox.insert(1, item)
Once I have all the values in the list box and it is scrollable which I would love if it was just damn.
listbox = tk.Listbox(root, height=1, scroll=auto)
I need to be able to use only the currency code which is the last value in the .csv file and use it as the selected value and then use it in a variable for the url. The .csv file looks like this.
Algeria د.ج DZD
Andorra € EUR
Angola Kz AOA
Anguilla $ XCD
Antigua and Barbuda $ XCD
Argentina $ ARS
Armenia AMD
Aruba ƒ AWG
Ascension Island £ (*none*)
I am also trying pandas but am new to it because it looks much easier and cleaner to use.
csv_file = ('testCUR.csv')
df = pd.read_csv(csv_file)
saved_col = df['CODE']
for item in df:
listbox.insert(end, saved_col)
Always error. NameError: name 'end' is not defined.
Happens with END also

I was wondering how to correctly populate the listbox with values from a .csv file?
To insert text into a listbox you must give it an index to tell it where to insert. The index is a string that is either a number, or the string "end". In your case you used a variable named end, which of course doesn't exist.
You can insert the text like this:
listbox.insert("end", item)
And also why I cannot use the scroll bar correctly?
You haven't described why your scrollbar is not correct.
Making a scrollbar works requires two-way conversation. The scrollbar must be told what widget to scroll (via the command attribute, and the widget needs to know which scrollbar to update when it is scrolled (via the yscrollcommand or xscrollcommand attribute).
It's also good to explicitly set whether the scrollbar is horizontal or vertical, though in your case it's vertical which is the default.
And finally, it's generally the best practice to make the scrollbar and the widget being scrolled to have the same parent. You made the mistake of making the scrollbar a child of the listbox. Instead, make it a child of whatever the listbox is a child of. You also made the mistake of trying to make it the parent of the listbox before you created the listbox. A widget must exist before you can give it children.
Here is how to create the listbox and scrollbar:
listbox = tk.Listbox(root)
scrollbar = tk.Scrollbar(root, orient="vertical", command=listbox.yview)
listbox.configure(yscrollcommand=scrollbar.set)

Related

Qt: QFormLayout - How to find the row from the button

How to find the row number of QFormLayout() from a button which is in that row? I have a delete button on each row of the form. Such that if I click the delete button, that specific row will get deleted. For this, I am planning to use the command QtWidgets.QFormLayout.removeRow(row) command. I have defined the QFormLayout() within my def __init__(self): function like so.
self.attachForm = QFormLayout()
I also have an Add button which calls the self.attachBtn_clicked(self) function given below. So every time the Add button is clicked a new row is added. Any help will be appreciated.
def attachBtn_clicked(self):
hbox = QHBoxLayout()
self.attachForm.addRow('',hbox)
browseBtn = QPushButton("Open")
hbox.addWidget(browseBtn)
addAttachEdit = QLineEdit()
hbox.addWidget(addAttachEdit)
delAttachBtn = QPushButton("x")
delAttachBtn.setFixedSize(15,15)
delAttachBtn.clicked.connect(self.delAttachBtn_clicked)
hbox.addWidget(delAttachBtn)
The objective is now to write the self.delAttachBtn_clicked(self) function which will delete the specific row.
You can iterate through the rows and find the button that matches the sender.
def delAttachBtn_clicked(self):
for i in range(self.attachForm.rowCount()):
if self.sender() == self.attachForm.itemAt(i, QFormLayout.FieldRole).itemAt(2).widget():
self.attachForm.removeRow(i)
return
itemAt(2) is used since delAttachBtn is the 3rd item in each QHBoxLayout.

Listbox resizing itself when new data is added

I am trying to add information to my Listbox and keeping it the size I state when I configure it. Here is my code for the Listbox with the scrollbar and an image of what it looks like.
Picture of the listbox.
taskList = Listbox(setBox, bg="#1B2834",fg="white")
taskList.configure(width=183,height=39)
taskList.pack(side=LEFT,fill=BOTH)
taskScroll = Scrollbar(setBox)
taskScroll.configure(bg="#1B2834",width=18)
taskScroll.pack(side = RIGHT, fill = BOTH)
taskList.config(yscrollcommand = taskScroll.set)
taskScroll.config(command = taskList.yview)
Now, when i click a button the command is to execute this following code:
def savetasks():
#make tasks
letters = string.ascii_uppercase
result_str = ''.join(random.choice(letters) for i in range(4))
num = str(random.randrange(0,9))
taskIDnum = num+result_str
taskIDLBL = Label(taskList, text=taskIDnum,bg="#1B2834", fg="White")
taskIDLBL.configure(padx=20,pady=10)
taskIDLBL.pack()
This code works fine as well, creating new labels with a random ID but it resizes the listbox to look like this...
Picture of the list box after clicking the button to execute the command.
Lastly, the scroll bar is not scrollable and when I create a lot of id's that end up going off my screen I cannot use the scroll bar to scroll down to see them, is there a way to not let the Listbox be resized and is it possible to set the Listbox with max and min-height?
If there is an easier way to do this without using a Listbox please let know, I just need to able to scroll down to see all the other id's and I didn't see any other way to use a scroll bar, that I NEEDED to use a Listbox

I need help in Python with displaying the contents of a 2D Set into a Tkinter Textbox

Disclaimer: I have only begun to learn about Python. I took a crash course just to learn the very basics about a month ago and the rest of my efforts to learn have all been research thru Google and looking at solutions here in Stack Overflow.
I am trying to create an application that will read all PDF files stored in a folder and extract their filenames, page numbers, and the contents of the first page, and store this information into a 2D set. Once this is done, the application will create a tkinter GUI with 2 listboxes and 1 text box.
The application should display the PDF filenames in the first listbox, and the corresponding page numbers of each file in the second listbox. Both listboxes are synched in scrolling.
The text box should display the text contents on the first page of the PDF.
What I want to happen is that each time I click a PDF filename in the first listbox with the mouse or with up or down arrow keys, the application should display the contents of the first page of the selected file in the text box.
This is how my GUI looks and how it should function
https://i.stack.imgur.com/xrkvo.jpg
I have been successful in all other requirements so far except the part where when I select a filename in the first listbox, the contents of the first page of the PDF should be displayed in the text box.
Here is my code for populating the listboxes and text box. The contents of my 2D set pdfFiles is [['PDF1 filename', 'PDF1 total pages', 'PDF1 text content of first page'], ['PDF2 filename', 'PDF2 total pages', 'PDF2 text content of first page'], ... etc.
===========Setting the Listboxes and Textbox=========
scrollbar = Scrollbar(list_2)
scrollbar.pack(side=RIGHT, fill=Y)
list_1.config(yscrollcommand=scrollbar.set)
list_1.bind("<MouseWheel>", scrolllistbox2)
list_2.config(yscrollcommand=scrollbar.set)
list_2.bind("<MouseWheel>", scrolllistbox1)
txt_3 = tk.Text(my_window, font='Arial 10', wrap=WORD)
txt_3.place(relx=0.5, rely=0.12, relwidth=0.472, relheight=0.86)
scrollbar = Scrollbar(txt_3)
scrollbar.pack(side=RIGHT, fill=Y)
list_1.bind("<<ListboxSelect>>", CurSelect)
============Populating the Listboxes with the content of the 2D Set===
i = 0
while i < count:
list_1.insert(tk.END, pdfFiles[i][0])
list_2.insert(tk.END, pdfFiles[i][1])
i = i + 1
============Here is my code for CurSelect function========
def CurSelect(evt):
values = [list_1.get(idx) for idx in list_1.curselection()]
print(", ".join(values)) ????
========================
The print command above is just my test command to show that I have successfully extracted the selected item in the listbox. What I need now is to somehow link that information to its corresponding page content in my 2D list and display it in the text box.
Something like:
1) select the filename in the listbox
2) link the selected filename to the filenames stored in the pdfFilename 2D set
3) once filename is found, identify the corresponding text of the first page
4) display the text of the first page of the selected file in the text box
I hope I am making sense. Please help.
You don't need much to finish it. You just need some small things:
1. Get the selected item of your listbox:
selected_indexes = list_1.curselection()
first_selected = selected_indexes[0] # it's possible to select multiple items
2. Get the corresponding PDF text:
pdf_text = pdfFiles[first_selected][2]
3. Change the text of your Text widget: (from https://stackoverflow.com/a/20908371/8733066)
txt_3.delete("1.0", tk.END)
txt_3.insert(tk.END, pdf_text)
so replace your CurSelect(evt) method with this:
def CurSelect(evt):
selected_indexes = list_1.curselection()
first_selected = selected_indexes[0]
pdf_text = pdfFiles[first_selected][2]
txt_3.delete("1.0", tk.END)
txt_3.insert(tk.END, pdf_text)

Combobox values appearing as single string characters

I am new posting to the forums & utilizing python/tkinter in order to create an electronic form to gather issues from manufacturing floor.
I have a (2) comboboxes.
The 1st combobox gains its "values" from a given dictionary.keys() which updates the "values" of a 2nd combobox. However, when selecting the values for the 2nd combobox after selecting for the 1st combobox, the values only show singular characters from the dictionary.values().
Here is the list from the txt file. The first item on each line is the key, while the rest of the items on the same line are its values.
Bondshop, Plies: Layup Difficulty, Plies: Cutting Edge
IB Postbond, POU, Equipment, Inspection, Available Work Space, Big Paint, 1575, QN
General Postbond, Inspection
Seal Area, Inspection
Big Paint, Inspection
Deflash, Inspection
Why does my 2nd combobox appear as so? See below.
"...show singular characters"...
===snip===
def loadcategory(self):
# Reads production areas & cateogries from dictCategory.txt file
self.textfileCategory = open('dictCategory.txt', 'r')
self.lines_category = self.textfileCategory.readlines()
for line in self.lines_category:
splitLine = line.split(',')
dict_category[str(splitLine[0])] = ",".join(splitLine[1:])
self.textfileCategory.close()
===snip===
def UpdateData(self, event):
# Updates Category Combobox based on Production Area selection
self.menu_category.set('---')
category = self.menu_production_area.get()
self.menu_category['values'] = sorted(dict_category[category])
===snip===
self.menu_production_area = ttk.Combobox(Main_Frame, state='readonly', values = sorted(list(dict_category.keys())), width=25)
self.menu_production_area.bind('<<ComboboxSelected>>', self.UpdateData)
self.menu_production_area.grid(row=2, column=1, sticky='w')

Tkinter insert a Combobox inside a Treeview widget

For example, lets create a Treeview widget using a class as follows:
class FiltersTree:
def __init__(self, master, filters):
self.master = master
self.filters = filters
self.treeFrame = Frame(self.master)
self.treeFrame.pack()
self._create_treeview()
self._populate_root()
def _create_treeview(self):
self.dataCols = ['filter', 'attribute']
self.tree = ttk.Treeview(self.master, columns = self.dataCols, displaycolumns = '#all')
Populate root, insert children as usual. At the end of the codeblock, you can see where I want to put a Combobox in the tree, using a Combo object:
def _populate_root(self):
# a Filter object
for filter in self.filters:
top_node = self.tree.insert('', 'end', text=filter.name)
# a Field object
for field in filter.fields:
mid_node = self.tree.insert(top_node, 'end', text = field.name)
# insert field attributes
self.insert_children(mid_node, field)
def insert_children(self, parent, field):
name = self.tree.insert(parent, 'end', text = 'Field name:',
values = [field.name])
self.tree.insert(parent, 'end', text = 'Velocity: ',
values = [Combo(self)]) # <--- Combo object
...
Next the class definition of Combo follows. The way I understand it, the combobox widget inherits from and must be placed inside the Labelframe widget from ttk:
class Combo(ttk.Frame):
def __init__(self, master):
self.opts = ('opt1', 'opt2', 'etc')
self.comboFrame = ttk.Labelframe(master, text = 'Choose option')
self.comboFrame.pack()
self.combo = ttk.Combobox(comboFrame, values=self.opts, state='readonly')
self.combo.current(1)
self.combo.pack()
So is this completely wrong? I want to have the ability to change between units (eg m/s, ft/s, etc) from within the Treeview widget.
Any suggestions, plz?
The treeview widget doesn't support embedded widgets. The values for the values attribute are treated as strings.
By default, a Treeview is a static display of a forest of lists of strings. However, with work, after carefully reading Treeview references, one can make a Treeview fairly interactive. For this question, I would bind left click to an event handler that compares the mouse x,y to the bounding box (.bbox) for the units attribute cell. If in the box, display a Combobox, initialized with the current value (such as 'flops'), directly on top of the units attribute cell.
Tkinter.ttk Treeview reference and Tcl/tk treeview reference
Of course, it might be easier to put the Treeview in a frame with with a separate Combobox.

Resources