I wanna build GUI and there is a button which Combobox adds every time the button is pressed. but i cant find out how to figure or code this concept
And, is there any other Widget? or is there other way to build my concept??
please some one help me..
the main concept without using tkinter is Like this shown . i want this concept to be made in Tkinter.
[THIS IS WHAT I TRIED BUT WHENEVER I PRESS THE BUTTON, ALL COMBOBOX ADDED WORKS TOGETHER (which means when i change the list name, all combobox also changes..)]
def Plus_EXT():
button_plus = Button(window3,justify = CENTER,command = Add_EXT, text= "+")
button_plus.grid(row=0,column=0)
def Add_EXT():
global Num
window3.update()
Num += 1
CEList1 = [x for x in os.listdir(cur_dir) if ('CE' in x.upper()) and ('.rpt' in x)]
RPT_EXT_file=ttk.Combobox(window3, values=CEList1,textvariable= EXT_String)
RPT_EXT_file.grid(row=8+Num,column=1)
RPT_EXT_file.set("FILE")
[MAIN CONCEPT WITHOUT USING TKINTER]
CE_Num= int(input("How Many EXTRA Chordae?: "))
User_File = input("Type the New File Name: ")
for Num_Of_EXT in range(CE_Num):
RPT_EXT_file = input("Type the RPT of EXTRA CHORDAE: ") + ".rpt"
EXTRA(User_File,RPT_EXT_file,Num_Of_EXT)
EXTRA_PLT(User_File,Num_Of_EXT)
the output i want is { everytime i press the button a new Combobox is added in the frame with the lists which works separately.}
The issue is that all your Combobox widgets are linked with same textvariable called EXT_String.So when you change the value of one Combobox widget, it updates same value in all of them.
I would suggest to keep a list of such variables and index that list using NUM in your loop to assign the textvariable.
UPDATE:
Just an example based on limited code shared in Add_EXT method:
global var_list
var_list.append(IntVar()) #Or StringVar(), whatever you are using
RPT_EXT_file=ttk.Combobox(window3, values=CEList1,textvariable=var_list[-1])
Related
I have built a application which contained multi QComboBox.
On change, each one add buttons (about 100) in a grid layout, here a part of the called function:
for x in xrange(1,100):
my_list_shots.append(str(x))
x=2 # line 1 has the menu
y=1 # row
incrementLineX=1 # every 10 we go to line 2 (x+1) and reset incrementLine and y (row) to 1
for i in xrange(1,121):
try:
my_shot_number=my_list_shots[i]
my_shot_number = "%03d"%int(my_shot_number)
self.buttons = QtWidgets.QPushButton(my_shot_number,self)
self.buttons.setStyleSheet("background-color:brown;color:white")
self.buttons.clicked.connect(partial(self.my_open_mov,my_shot_number))
self.my_grid_layout.addWidget(self.buttons,x,y,1,1)
except Exception as e:
self.buttons = QtWidgets.QPushButton("",self)
self.buttons.setEnabled(False)
my_shot_number=""
y=y+1
incrementLineX=incrementLineX+1
if incrementLineX>10:
x=x+1
y=1
incrementLineX = 1
self.buttons.clicked.connect(partial(self.my_open_mov,my_shot_number))
and so on...
I worried about the memory, if I keep my window open all day long with many changes, I'll create each time 99 buttons? or not..?
How can I properly build my buttons?
Do I need to destroy them when I call the function?
In another way, what I want is to replace new buttons by old ones and I don't want to create thousand of buttons if I keep the windows open.
I just need the way to do it.
I have got the solution.
I use deleteLater() for each created buttons before to rebuild new ones.
# DELETE THE OLD WIDGET IN THE LAYOUT GRID
def clearShotsWidget(self):
while self.shotsWidgetLayout.count():
item = self.shotsWidgetLayout.takeAt(0)
item.widget().deleteLater()
self.shotsWidgetLayout.removeItem(item)
The other idea is to put all the build buttons in a list and delete them before to create the new ones.
Thanks a lot
Gui
I wrote the below code to bind event and do operations on individual listbox items.
import tkinter as tk
root = tk.Tk()
custom_list = tk.Listbox(root)
custom_list.grid(row=0, column=0, sticky="news")
def onselect_listitem(event):
w = event.widget
index = int(w.curselection()[0])
value = w.get(index)
print(index, value, " color : ",custom_list.itemcget(index,'background'))
custom_list.itemconfig(index, fg='gray', selectforeground="gray")
custom_list.bind('<Double-Button-1>', onselect_listitem)
for k in range(20):
custom_list.insert(k, " --------- " + str(k))
root.mainloop()
I am having trouble using itemcget to get the background properties while itemconfig works properly. Everything else is working. Can someone tell me if there is something wrong? I am trying to obtain the current item background color via index of the item in the listbox. The part with custom_list.itemcget doesn't print anything.
Thanks
From the New Mexico tech Tkinter reference:
.itemcget(index, option)
Retrieves one of the option values for a specific line in the listbox. For option values, see itemconfig below. If the given option has not been set for the given line, the returned value will be an empty string.
So since you haven't set the background option, itemcget returns an empty string. You can see this working by changing the print to custom_list.itemcget(index,'fg'). The first time you doubleclick you get an empty sting because you haven't set it, the second time it prints gray.
I wrote this code (actually using Jupyter-Notebook):
import random
from ipywidgets import widgets
for ind in range(0,10):
print('Some text'+str(ind))
cb_inner = []
a = random.randint(0,3)
for el in range(0,3):
cb_value = True if el == a else False
A = widgets.Checkbox(value=cb_value, description='cb'+str(el))
cb_inner.append(A)
for_box_list = cb_inner
box = widgets.HBox(for_box_list)
display(box)
print('---'*41)
Now I have text strings and line of chackboxes for each. Only one checkbox active at the time. If I check another checkbox both of them become checked. What I want to do: if I check another checkbox, first one become disabled automatically (for group of checkboxes for every text message).
I suppose I need to create event for this. I found this:
Python ipywidgets checkbox events
But I can't understand how to implement it for all my boxes?
I thought a lot about list of checkboxes and creating events for them in a loop, but finally found simple way:
using RadioButtons. To handle the situation where all checkboxes in a line are turned off, I just added one more option in RadioButton arguments:
from ipywidgets import widgets
buttons_list = []
for ind in range(0,10):
print('My message',ind)
rb = widgets.RadioButtons(options=['cb1', 'cb2', 'noone checked'],
value='cb1')
display(rb)
print('---'*41)
buttons_list.append(rb)
In this example, if a user selects any option in any of the drop downs, then clicks on another drop down, the previously selected item displayed a check mark beside it. Even though that choice was picked in a different menu.
from Tkinter import *
from ttk import *
choices = ['1st Choice', '2nd Choice', '3rd Choice', '4th Choice']
root = Tk()
for each in range(10):
OptionMenu(root, StringVar(), choices[0], *choices).pack()
root.mainloop()
This happens on both Python 2.7 and 3.5.
I've even moved the choices list into the loop so it generates on each iteration and the problem still occurs. I'm assuming since the elements of the list are the same objects tkinter isn't differentiating between which OptionMenu they are in. It would seem I need a unique list every time through the loop.
Is there any way to limit the check mark to displaying only on the OptionMenu that the user has interacted with?
This is a bug in the ttk implementation of OptionMenu. It isn't assigning a unique variable for the radiobuttons in each OptionMenu.
You can fix this with a little bit of code. Basically, you have to loop over every item in the menu and set the variable attribute.
Here's an example:
def optionmenu_patch(om, var):
menu = om['menu']
last = menu.index("end")
for i in range(0, last+1):
menu.entryconfig(i, variable=var)
...
for each in range(10):
sv = StringVar()
om = OptionMenu(root, sv, choices[0], *choices)
om.pack()
optionmenu_patch(om, sv)
Bug tracker issue: http://bugs.python.org/issue25684
I am writing a Tkinter program for the first time and have a question on radio buttons. What I am trying to do is this:
open a set of images (one at a time).
When an image is opened, annotate a value using the radio button.
Collect this value in a list
So, in this example I have 2 compounds and the list would have 2 annotations.
The problem I have is, if by mistake the user clicks radiobutton 2 instead of one, and then corrects him/herself, the list will have 4 items (3 for the first image, 1 for the second). How do I handle this, so that the list will have only 2 values?
import Tkinter as tk
from PIL import ImageTk, Image
from tkFileDialog import askopenfilename
cmp_list = ["VU435DR","VU684DR"]
li = []
li_final = []
def sel():
selection = str(var.get())
if selection == "1":
li.append("Antagonist")
elif selection == "2":
li.append("Agonist")
for i in range(len(cmp_list)):
root = tk.Tk()
var = tk.IntVar()
ig = str(cmp_list[i] + '.png')
img = ImageTk.PhotoImage(Image.open(ig))
panel = tk.Label(root,image=img)
panel.pack(side = "top",fill="none",expand="no")
#w = tk.Text(height=2,width=50)
#w.pack(side='right")
q = tk.Radiobutton(root,text="Antagonist",command=sel,value=1,variable=var)
q.pack()
r = tk.Radiobutton(root,text="Agonist",command=sel,value=2,variable=var)
r.pack()
root.mainloop()
print li
Your code is creating more than one instance of tk.Tk(). This is not how Tkinter was designed to work, and it will yield unpredictable behavior. A proper Tkinter program always has exactly one instance of tk.Tk().
If you need more than one window, for the second and subsequent windows you should create an instance of tk.Toplevel.
To answer your specific question about how to handle someone first hitting one radiobutton and then the other -- the problem is that you are unconditionally appending to your list each time they click on a radiobutton. The solution is to use some sort of flag or indicator to know whether one of the radiobuttons has been clicked, or change your code so that it doesn't matter.
Let's look at that second option - make it so it doesn't matter. When you open up a new image you can automatically append a value to your list. In this case, set it to None to say that nothing has been picked yet. Then, in sel, you would always replace the last element rather than append a new element, since you know that the last element always refers to the current compound.