I made a code for a program that will show pictures that are accessible from the main menu. In my menu, there is a search option that opens a new window in which you can search through the database (that's a list) and if the entered words are in the list it will activate a function. the search function is shown in this part of code:
def search():
def compare(words):
key=words.get()
print(key)
for i in base:
if i==key:
if key=="apple":
AppleFunction()
if key=="pear":
PearFunction()
else:
messagebox.showerror("Eror!","Wrong entry, please correct!")
return
searchWindow=Toplevel(main)
searchWindow.geometry("425x125+225+145")
searchWindow.resizable(False,False)
searchWindow.config(bg=mycolor)
searchWindow.title("Search")
searchWindow.iconbitmap(r"f.ico")
words=Entry(searchWindow)
words.config(font="Times", width=20)
text1=Label(searchWindow, text="Search by key words:", wraplength=250, justify="center")
text1.pack(pady=5)
text1.config(bg=mycolor, font="Times")
words.pack(pady=5)
picture1=PhotoImage(file="ttt.gif")
searchButton=Button(searchWindow, image=picture1, height=19)
searchButton.config(bg=mycolor)
searchButton.bind("<Button>", compare(words))
searchButton.pack(pady=5)
searchWindow.mainloop()
return
It is all made with Tkinter module. I tried with global variables and arguments with functions, but there was no error. Although there is no error, the program still doesn't work. Can someone help me solve the problem?
So, I solved the problem by making the Entry global and giving the inner function that compares the strings the "event" argument. Here is the correct code:
def search():
def compare(event):
key=str(words.get())
for i in base:
if i==key:
if key=="Apple":
AppleFunction()
elif key=="Pear":
PearFunction()
else:
messagebox.showerror("Error!","Wrong entry, please correct!")
return
searchWindow=Toplevel(main)
searchWindow.geometry("425x125+225+145")
searchWindow.resizable(False,False)
searchWindow.config(bg=mycolor)
searchWindow.title("Tražilica")
searchWindow.iconbitmap(r"f.ico")
text1=Label(searchWindow, text="Search by key words:", wraplength=250, justify="center")
text1.pack(pady=5)
text1.config(bg=mycolor, font="Times")
global words
words=Entry(searchWindow)
words.config(font="Times", width=20)
words.pack(pady=5)
picture1=PhotoImage(file="ttt.gif")
searchButtton=Button(searchWindow, image=picture1, height=19)
searchButtton.config(bg=mycolor)
searchButtton.bind("<Button>", trazi)
searchButttonb.pack(pady=5)
searchWindow.mainloop()
return
Although, when I exit the program, it shows me the error message that I created for a case when the string doesn't match and opens a random new empty Tkinter window which shouldn't be happening because while the program was running it has found by keywords correctly what I was looking for and gave me the correct picture. Also, There was this error on the Console (but not in Shell):
invalid command name ".!toplevel.!button"
while executing
"$w cget -relief"
(procedure "tk::ButtonDown" line 9)
invoked from within
"tk::ButtonDown .!toplevel.!button"
(command bound to event)
Related
I'm trying to create a gradio User Interface which does the following
on the left panel I have a File control, that allows the selection of a local file (eg. a .csv)
when a file is selected a "Process" button should be made visible
when the "Process" button is pressed, a function is called, reading the contents of the file, and processing it in some ways, resulting in a string
the resulting string is shown in a TextArea in the right column
I'm stuck implementing point 2. I can select the file, but can't make the Process button become visible.
This is my code so far (not yet implementing points 3. a:
import gradio as gr
def file_selected(file_input):
print("yes, file_selected is invoked")
print(process_button)
process_button.visible=True
demo.render()
return process_button
with gr.Blocks() as demo:
with gr.Row():
with gr.Column(scale=1):
gr.Markdown("### Data")
file_input = gr.File(label="Select File")
process_button = gr.Button("Process", visible=False)
with gr.Column(scale=2, min_width=600):
gr.Markdown("### Output")
result_display = gr.TextArea(default="", label="Result", lines=10, visible=False)
file_input.change(fn=file_selected, inputs=file_input, outputs=process_button)
if __name__ == "__main__":
demo.launch()
I see that at file selection the message is printed (and print(process_button) prints "button" so I'm sure this variable is not None), but the button doesn't appear on the page.
edited: fixed some errors not directly related to the problem.
There were many problems with the code (I fixed those not related with the main issue in the original post), but in the end what solved my problem (making the button visible) was that instead to rerender,
def file_selected():
...
process_button.visible=True
demo.render()
I just had to return the process_button.update
def file_selected(file_input):
...
return gr.update(visible=True)
(Actually this was documented in gradio's online docs; sorry, I didn't notice it before)
This is the complete working code:
import gradio as gr
def file_selected(file_input):
print("yes, file_selected is invoked")
print(process_button)
return gr.update(visible=True)
with gr.Blocks() as demo:
with gr.Row():
with gr.Column(scale=1):
gr.Markdown("### Data")
file_input = gr.File(label="Select File")
process_button = gr.Button("Process", visible=False)
with gr.Column(scale=2, min_width=600):
gr.Markdown("### Output")
result_display = gr.TextArea(default="", label="Result", lines=10, visible=False)
file_input.change(fn=file_selected, inputs=file_input, outputs=process_button)
if __name__ == "__main__":
demo.launch()
I have been trying to put together a few lines of code that takes a youtube music video URL and converts it to mp3/mp4 + 720p, and then downloads it to my DropBox music folder.
When I'm trying to pass a URL through a TKinter widget (entry bar) I am hitting an error about how the the entry object has no attribute 'type', or that the URL is invalid. Is it something to do with not adding quotation marks to the youtube link or something?
If anyone has any insight I would greatly appreciate it. I assume I'm missing something very obvious, but I can't seem to figure out what exactly.
#!/usr/bin/env python
import sys
import os
import tkinter
from pytube import *
from tkinter import *
top=tkinter.Tk()
yt_variable = StringVar()
def helloCallBack():
#Select youtube link you want to upload and print contents
yt = YouTube(yt_entry)
print(yt.get_videos())
print(yt.filename)
#Set parameters for youtube video
video = yt.get('mp4', '720p')
print(yt.videos)
print("success")
#Select download location for youtube video
video.download('C:/Users/coope/Dropbox/BrokenBow/Music/')
print("Downloaded " + str(yt.filename) + " to " + str(video.download) + " successfully!")
return
yt_label=tkinter.Label(top,text='Paste Link + Press Go')
yt_label.pack()
yt_button=tkinter.Button(top,text='Go',command= helloCallBack)
yt_button.pack()
yt_entry=tkinter.Entry(top, textvariable=yt_variable)
yt_entry.get()
yt_entry.pack()
top.mainloop()
Briefly, you have the following:
yt_entry=tkinter.Entry(top, textvariable=yt_variable)
yt_entry.get()
yt = YouTube(yt_entry)
You are expecting this to create an Entry widget, retrieve its contents, and send that retrieved value to the YouTube() constructor. It does not work like that. You are actually creating an Entry widget, immediately retrieving its contents, throwing away those contents (which will be empty anyway, since by that point you haven't had a chance to put anything into that field), and then attempting to send the Entry widget itself to the YouTube() constructor.
On top of that, you give the Entry widget a textvariable, but then you never use it.
Instead, retrieve the contents of that Entry widget (via its textvariable) within the callback. You can even do it in the YouTube() constructor call.
...
top=tkinter.Tk()
yt_variable = StringVar()
def helloCallBack():
...
yt = YouTube(yt_variable.get())
...
...
yt_entry=tkinter.Entry(top, textvariable=yt_variable)
yt_entry.pack()
top.mainloop()
Since you're not doing anything special with that Entry widget, there's no need for a textvariable at all.
...
top=tkinter.Tk()
def helloCallBack():
...
yt = YouTube(yt_entry.get())
...
...
yt_entry=tkinter.Entry(top,)
yt_entry.pack()
top.mainloop()
Also, there's no need for a bare return at the end of a function. It will return regardless once there's nothing more to do, with a default return value of None (the same as what gets returned with a bare return statement, or with return None).
I'm currently designing a code for a troubleshooter. My problem is that when I press "other", there should be a data entry form label, which there is. But when i type something into it and press continue, it shows an error that says "
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Python33\lib\tkinter\__init__.py", line 1482, in __call__
return self.func(*args)
File"R:\ICT\ControlledAssessment_15_17\Computing\Unit3\RiddhiSharma\FinalTroubleshooter.py", line 15, in click
display.insert(END, key)
NameError: global name 'display' is not defined
I think the problem in my actual code is here:
def click():
display.insert(END, key)
output.delete(0.0, END)
try:
entered_text=entry.get()
definition = my_glossary[entered_text]
except:
definition = "There is no entry for this word."
output.insert(END, definition)
Apparently display is not part of the tkinter module or it is not defined altogether. So when you try to use it, it raises an error because you have not defined display as a variable, function, class etc. So define display is a function that takes two arguments, END and key.
When defining display. You could do something like this:
display = 123
You could also make it a ENTRY, or whatever display is supposed to be. In your case, display doesn't have to be equal to 123. It could be equal to a class:
display = Display()
Just define Display() first... but display can be anything you want, as long you define it and use it correctly.
#PythonMaster thanks a lot for your help. To solve my problem I replaced the display function and wrote the code out like this:
def click():
entered_text = entry.get()
output.delete(0.0, END)
try:
definition = my_glossary[entered_text]
except:
definition = "There is no entry for this word."
output.insert(END, definition)
I am trying to get my program to record if the user clicked on checkbox(es) so I know what things to delete. The problem is that I don't have all the variables names for all the checkboxes so I can't just do GetValue(). In the code below, I have a set number of things but in the actual program, it pulls user info from file.
import wx
class supper(wx.Frame):
def __init__(self,parent,id):
wx.Frame.__init__(self,parent,id,'Delete Stocks',size=(300,300))
nexus=wx.Panel(self)
again=30
newfp='GOOG AAPL'.split()
#Need to see if user checked box and which one
for i in newfp:
self.checkbox=(wx.CheckBox(nexus,-1,i,(30,again),(160,-1)))
self.Bind(wx.EVT_CHECKBOX, self.lol,self.checkbox)
again+=30
anothercancel=wx.Button(nexus,label='Cancel',pos=(50,250),size=(60,40))
self.Bind(wx.EVT_BUTTON,self.acancel,anothercancel)
anotherok=wx.Button(nexus,label='OK',pos=(200,250),size=(60,40))
self.Bind(wx.EVT_BUTTON,self.okalready,anotherok)
def acancel(self,event):
self.Destroy()
#Couldn't figure out how to see what check was clicked
def okalready(self,event):
for i in newfp:
valuechecker=self.checkbox.GetValue()
if self.checkbox.Get()==True:
print 'You clicked this %s one'%i
self.Destroy()
def lol(self,event):
pass
if __name__=='__main__':
ok=wx.PySimpleApp()
people=supper(parent=None,id=-1)
people.Show()
ok.MainLoop()
This isn't the whole thing so there might be a variable that is not defined here. Thanks in advance! Look forward to the answers!
just keep them in a list ...
self.checkboxes = []
for i in newfp:
self.checkboxes.append(wx.CheckBox(nexus,-1,i,(30,again),(160,-1)))
self.checkboxes[-1].Bind(wx.EVT_CHECKBOX, self.lol)
again+=30
then to check which boxes are checked when you click ok you can use this
def okalready(self,event):
for i,cb in enumerate(self.checkboxes):
print "CB:%d = %s"%(i,cb.GetValue())
print "Checked:",[cb.GetLabel() for cb in self.checkboxes if cb.GetValue()]
self.Destroy()
I'm using python 2.7.5 on mac OSX
in my code I have a function that needs to return a value. Within the function I want my callback function (tkinter) to make it's parent function to return a value, but if there is a better way to do this please say. Sorry if I'm being un-clear because I'm not sure how to explain my problem.
def Open():
class dataC:
lines=[]
data=dataC
def event():
path=pathE.get()
file=fileE.get()
try:
os.chdir(path)
temp=open(file)
lines=temp.readlines()
temp.close()
except:
lines=[]
else:
os.chdir(path)
temp=open(file)
lines=temp.readlines()
temp.close()
data.lines=lines
gui=Tk()
gui.title("Open File")
pathE=Entry(gui)
pathE.pack(padx=5,pady=5)
pathE.insert(INSERT,startingDir)
fileE=Entry(gui)
fileE.pack(padx=5,pady=5)
fileE.insert(INSERT,"File Name")
openE=Button(gui,text="Open File",command=event)
openE.pack(padx=5,pady=5)
gui.mainloop()
Since you want to return a value in Open() I assume that the mainloop should be quit as soon as the button is clicked. So you have to add the line
gui.quit()
or
gui.destroy()
in event(). You can save the value you want to return in a local variable of Open() while you are in event(), like you already do with data and then return it after the mainloop line.