My Whole Program is Working in a Loop like this
myWindow = Tk()
myWindow.title("Live Data")
myWindow.geometry("500x600")
def my_mainloop():
statements....
myWindow.after(1000, my_mainloop)
myWindow.after(1000, my_mainloop)
myWindow.mainloop()
I want to implement something(button/checkbox), which is changing a value in variable
like 0 and 1
so i can use this value (0/1) in this infinite loop to code my logic
A Click will change value to 1 and then another click will change value to 0.
Thank you.
my example:
def change_value(*arg):
value = 1
button(myWindow, text, command=change_value)
Related
I work with tkinter. I want to change the name of the labels. By entering the characters in the field and hitting the button, the labels are renamed one by one. That is, the first time I enter the character "Hello", then that character is inserted in the label; It is then removed from the field. This time I have to enter a character for the next label. And so on until the end
(With the help of the for loop).
I did this but it only works for the first label and does not go to the next label):
win=Tk()
size=3
lbls=[]
frms=[]
def func():
for i in range(6,9):
lbls[i].configure(text=name.get())
for i in range(size):
for j in range(size):
frm=Frame(win,bd=2,relief="sunken")
frm.grid(row=i,column=j)
frms.append(frm)
lbl=Label(frm,bg="white",fg="red",width="5")
lbl.grid(row=0,column=0)
lbls.append(lbl)
name=Entry(win)
name.grid(row=4,column=0)
btn=Button(win,text="Start",font=("Arial",14),command=func)
btn.grid(row=3,column=0)
win.mainloop()
You need to use a counter and increase it inside the function. Basically, for loop wont wait for you to type in something and press the button:
counter = 0
def func():
global counter
lbls[counter].configure(text=name.get())
counter += 1 # Increase it by 1
if counter >= len(lbls): # If counter is greater than items in list, then reset
counter = 0
name.delete(0,'end') # Clear the entry
This will keep updating the text each time you press the button.
Some designing tip: Add columnspan for your button and entry
name.grid(row=4,column=0,columnspan=3)
btn.grid(row=3,column=0,columnspan=3)
This question already has answers here:
tkinter creating buttons in for loop passing command arguments
(3 answers)
Closed 1 year ago.
I am making GUI and have some problems on the button command which is used to clear the input value .When i input a value into the 1st entry and try to click the 1st button , the value is not erased which should be cleared, Same as the 2nd button.But for the 3rd button ,it can clear the 3rd input value ,and the 1st,2nd button can also erase the value on 3rd entry.I want the 1st entry to 1st button and can erase data .What's wrong with my code .How should i modify it .Your help is very gratefully appreciated.
Here is my code:
from tkinter import *
root = Tk()
screenwidth = root.winfo_screenwidth()
screenheight = root.winfo_screenheight()
root.title('PN List Box')
root.geometry("500x300+%d+%d"%((screenwidth-400)/2,(screenheight-230)/2-100))
mycolor = '#%02x%02x%02x' % (101, 119, 141)
root.configure(bg=mycolor)
cv = Canvas(root,bg=mycolor)
dict1={}
dict2={}
list1=[]
label_rely=0
for a in range(3):
label_rely+=0.1
list1.append(StringVar())
dict1[a]=Entry(root,textvariable=list1[a]).place(relx=0.27, rely=0.33 + label_rely)
dict2[a]= Button(root,text='clear',command=lambda :list1[a].set('')).place(relx=0.86,rely=0.32+label_rely)
root.mainloop()
sys.exit()
This is a tricky little corner of Python. Remember that your lambda function isn't evaluated until the lambda is actually executed. By the time the lambda is executed, a has the value 2, for all three callbacks. What you need to do is "capture" the loop value, by passing it as a default parameter to the function:
dict2[a]= Button(root,text='clear',command=lambda a=a :list1[a].set('')).place(relx=0.86,rely=0.32+label_rely)
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])
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 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.