New window opens on click but does not show anything[Tkinter] - python-2.7

I am using root as the primary window in which when one puts a question, then the answer from either Wikipedia or WolframAlpha is shown in a new window. But, here what happens is that the new window properly opens but does not show anything.
from Tkinter import *
import wolframalpha
import wikipedia
root=Tk()
root1=Tk()
def getinput():
global entry
answer = StringVar()
ques=entry.get()
try:
#wolframalpha
app_id = myappid #value of myappid is there in the original code
client = wolframalpha.Client(app_id)
res = client.query(ques)
answer.set(next(res.results).text)
label=Label(root1, textvariable=answer)
except:
#wikipedia
answer.set(wikipedia.summary(ques).encode('utf-8'))
label=Label(root1, textvariable=answer)
label.pack(side=BOTTOM)
root.geometry("350x80+300+300")
label=Label(root, text="Hi! I am Python Digital Assistant. How can I help you today?")
entry=Entry(root)
submit=Button(root, text="Submit", bg="light green", command=getinput)
exit1=Button(root, text="Exit", bg="red", fg="white", command=root.destroy)
label.pack()
entry.pack(fill=X)
entry.focus_set()
submit.pack(side=LEFT)
exit1.pack(side=LEFT)
root.mainloop()

You don't have to call TK twice you have to use toplevel to achieve that , with that when you provide the question and click on the submit method the answer will pop up in the Toplevel window.
from Tkinter import *
import wolframalpha
import wikipedia
root=Tk()
def getinput():
top = Toplevel()
top.geometry("500x500")
global entry
answer = StringVar()
ques=entry.get()
try:
#wolframalpha
app_id = myappid #value of myappid is there in the original code
client = wolframalpha.Client(app_id)
res = client.query(ques)
answer.set(next(res.results).text)
label=Label(top, textvariable=answer)
except:
#wikipedia
answer.set(wikipedia.summary(ques).encode('utf-8'))
label=Label(top, textvariable=answer)
label.pack(side=TOP)
root.geometry("350x80+300+300")
label=Label(root, text="Hi! I am Python Digital Assistant. How can I help you today?")
entry=Entry(root)
submit=Button(root, text="Submit", bg="light green", command=getinput)
exit1=Button(root, text="Exit", bg="red", fg="white", command=root.destroy)
label.pack()
entry.pack(fill=X)
entry.focus_set()
submit.pack(side=LEFT)
exit1.pack(side=LEFT)
root.mainloop()

Related

Non-blocking print redirection to Tkinter text widget

I've been able to get print statements redirected to a Tkinter text widget based on the answer to this question. It describes a class to redirect stdout:
class TextRedirector(object):
def __init__(self, widget, tag="stdout"):
self.widget = widget
self.tag = tag
def write(self, str):
self.widget.configure(state="normal")
self.widget.insert("end", str, (self.tag,))
self.widget.configure(state="disabled")
Utilizing the TextRedirector class, I have the following code
import sys
import time
from tkinter import *
root = Tk()
t = Text(root, width = 20, height = 5)
t.grid()
old_stdout = sys.stdout
sys.stdout = TextRedirector(t)
for i in range(5):
print i + 1
time.sleep(1)
sys.stdout = old_stdout
However, this solution seems to be blocking (the text shows up all at once once the for-loop ends).
I have successfully put together a non-blocking solution using Popen and threading, but this isn't an ideal solution due to some unrelated constraints.
Is there a way to have the print statements show up in the text box in real-time?

Adding notebook tabs in tkinter - how do I do it with a class-based structure? (Python 2)

I want each tab to come from it's own class (classes are in their own files - I am just testing the first one for now).
Here is what I tried:
tab1.py
from Tkinter import *
import Tkinter as tk
class Tab(tk.Frame):
def __init__(self, master):
tk.Frame.__init__(self, master)
fr = Frame(self).pack()
Label(fr, text="one", bg='red', bd=2).pack()
Label(fr, text="two", bg='yellow', bd=2).pack()
if __name__ == '__main__':
root = Tk()
frame = Frame(root).pack()
Tab(frame)
Button(frame, text='only if class', command=root.destroy).pack()
mainloop()
noteBook.py
from Tkinter import *
from ttk import *
from tab1 import Tab
root = Tk()
note = Notebook(root)
main_frame = Frame(note)
button1 = Button(main_frame, text='test').pack()
#tab1 = Tab(note)
tab1 = Frame(note)
tab2 = Frame(note)
tab3 = Frame(note)
Tab(tab1)
Button(tab1, text='Exit', command=root.destroy).pack()
note.add(tab1, text = "Tab One", compound=TOP)
note.add(tab2, text = "Tab Two")
note.add(tab3, text = "Tab Three")
note.pack()
root.mainloop()
exit()
run with:
python2.7 noteBook.py
The problem is that the content of tab1.py does not appear within the first tab, it instead appears within the frame that contains the whole noteBook.
Also when running tab1.py directly with python2.7 noteBook.py I need it to behave properly meaning from what it has now it should show just the tab with an extra button from the if __name___... part.
I have come accros multiple examples but only found one that was what I want but it had no working solution and it was for python3 - I would like python2. python3 question with no working answer Thanks.
The problem is this line of code:
fr = Frame(self).pack()
When you do the above, fr is None because .pack() returns None (because x().y() returns the value of y()). Later, you do this:
Label(fr, text="one", bg='red', bd=2).pack()
Since fr is None, the label is created in the root window.
Unrelated to the problem, here's some advice: you are creating too many frames. You don't need fr inside of Tab, and you don't need tab1, tab2, or tab3
Here's all you need for Tab:
class Tab(tk.Frame):
def __init__(self, master):
tk.Frame.__init__(self, master, background="pink")
Label(self, text="one", bg='red', bd=2).pack()
Label(self, text="two", bg='yellow', bd=2).pack()
To add it to the notebook, you just need two lines:
tab1 = Tab(note)
note.add(tab1, text = "Tab One", compound=TOP)
This works perfectly and just for fun I've illustrated the populating of tabs 2 and 3 althought I just reused the same class for simplicity here. The goal was to be able to run the tabs directly to view them alone during developpement without having to run the whole thing every time.
noteBook.py
from Tkinter import *
from ttk import *
from tab1 import Tab
root = Tk()
note = Notebook(root)
main_frame = Frame(note)
button1 = Button(main_frame, text='test').pack()
tab1 = Frame(note)
tab2 = Frame(note)
tab3 = Frame(note)
Tab(tab1)
Tab(tab2)
Tab(tab3)
Button(tab1, text='Exit', command=root.destroy).pack()
note.add(tab1, text = "Tab One", compound=TOP)
note.add(tab2, text = "Tab Two")
note.add(tab3, text = "Tab Three")
note.pack()
root.mainloop()
exit()
tab1.py
import Tkinter as tk
class Tab(tk.Frame):
def __init__(self, parent_widget):
tk.Frame.__init__(self, parent_widget)
self.fr = tk.Frame(parent_widget, width=200, height=200, bg='pink', bd=2)
tk.Label(self.fr, text="one", bg='red', bd=2).pack()
tk.Label(self.fr, text="two", bg='yellow', bd=2).pack()
self.fr.pack() # this packing must be done after 2 above packings
if __name__ == '__main__':
root = tk.Tk() # the app window
main_frame = tk.Frame(root, height=200, width=200, bg='blue', bd=2) # main frame
Tab(main_frame) # instatiate Tab(), sending main_frame as the parent_widget
tk.Button(main_frame, text='only if class', command=root.destroy).pack()
main_frame.pack() # display main frame on window
tk.mainloop()

tk button changes appearance

So I was doing this program and noticed that both my buttons look initially like this
And after I run my program for some time the second button changes it appearance to this
When does this happen?
Here's my code :/ in case I am doing something that should not be done. I am doing this in python 2.7.8 in IDLE.
import time
import Tkinter as tk
from Tkinter import StringVar
import threading
global root
root = tk.Tk()
x = tk.StringVar()
x.set('false')
def xval(*args):
try:
for i in range(0,9):
global x
print x.get()
if x.get()== 'false' :
print "x=false %d time"%i
time.sleep(1)
else:
print "waiting"
root.update()
except:
pass
def stop(event):
resume_btn.configure(state="normal")
global x
x.set('true')
print "execution stopped:%s"%x
def start(event):
global x
x.set('false')
print "execution started:%s"%x
xval()
root.title("GUI-Data Retrieval")
th = threading.Event()
t = threading.Thread(target=xval,args=(th,))
t.deamon=True
t.start()
x_btn = tk.Button(root, text="Stop", background="Snow", width=20, relief="raised")
x_btn.grid(row=0, column=4, sticky="W", padx=20, pady=5)
x_btn.bind('<Button-1>',stop)
resume_btn = tk.Button(root, text="Start", background="Snow", width=20, relief="raised")
resume_btn.configure(state="disabled")
resume_btn.grid(row=0, column=6, sticky="W", padx=20, pady=5)
resume_btn.bind('<Button-1>',start)
root.mainloop()
The problem is that your binding is handled before the default bindings. It is the default bindings that change the appearance of the button when it is clicked on. You are disabling the button on a click, preventing the default behavior from resetting the appearance of the button when you release the mouse button.
Unless there's a specific reason to do otherwise, you should use the command attribute of the button widget rather than try to create your own bindings.

how to display a form within a frame using python and tkinter

I have created a notebook(file1.py) using python and tkinter. This notebook has three tabs A,B,C. I have another python file(file2.py) which contains few text fields. Now I am looking for a way to display the contents of the other file2.py within the tab A which is in file1.py.The following is the code I used in file1.py
import tkinter as tk
import tkinter.ttk as ttk
root = tk.Tk()
# use width x height + x_offset + y_offset (no spaces!)
root.geometry("%dx%d+%d+%d" % (300, 200, 100, 50))
root.title('test the ttk.Notebook')
nb = ttk.Notebook(root)
nb.pack(fill='both', expand='yes')
# create a child frame for each page
f1 = tk.Frame(bg='red')
f2 = tk.Frame(bg='blue')
f3 = tk.Frame(bg='green')
# create the pages
nb.add(f1, text='A')
nb.add(f2, text='B')
nb.add(f3, text='C')
# put a button widget on child frame f1 on page1
btn1 = tk.Button(f1, text='button1')
btn1.pack(side='left', anchor='nw', padx=3, pady=5)
root.mainloop()
File2.py
import sys
from PyQt4 import Qt
from taurus.qt.qtgui.application import TaurusApplication
app = TaurusApplication(sys.argv)
panel = Qt.QWidget()
layout = Qt.QHBoxLayout()
panel.setLayout(layout)
from taurus.qt.qtgui.panel import TaurusForm
panel = TaurusForm()
model = [ 'test/i1/1/%s' % p for p in props ]
panel.setModel(model)
panel.show()
sys.exit(app.exec_())
I am new to using tkinter and python so could you let me know how I could achieve it. Also in the other file(file2.py) I have few import statements like 'import sys" etc.Thanks.
You cannot mix those two files. One uses Tkinter, one uses PyQT. Those two libraries are incompatible with each other.

Python Tkinter - Find image file path from PhotoImage

I have a PhotoImage in tkinter called al_p4 but I want to be able to print the file path of the image. Can anyone help. Here is my code:
al_p4 = Image.open("Media/DVD/image.jpg").resize((100, 150), Image.ANTIALIAS)
al_p4 = ImageTk.PhotoImage(al_p4)
Thanks in advance guys ;)
Because I'm still having trouble interpreting exactly what you mean, here are four different answers regarding how to go about printing.
If you simply need to print it and the path will always be constant, use:
print("Media/DVD/image.jpg")
If you need to print something and the path will be different, try:
filepath = "Media/DVD/image.jpg"
al_p4 = Image.open(filepath).resize((100, 150), Image.ANTIALIAS)
al_p4 = ImageTk.PhotoImage(al_p4)
print(filepath)
If you need to print something to a widget, it's going to depend on the kind of widget you want to use. For something small like a file path, a label would probably be good. Look at effbot's documentation for the label widget for more details.
If you want to redirect all print statements to a widget, which can be useful depending on how your GUI is designed, create a class to redirect stdout. Here's an example with a text widget:
import sys
import Tkinter
def nothing():
print("Nothing")
class Application(Tkinter.Frame):
def __init__(self, master = None):
Tkinter.Frame.__init__(self, master)
self.button = Tkinter.Button(text = "Button 1", command = nothing)
self.button.pack()
class StdoutRedirector(Tkinter.Text):
def __init__(self):
Tkinter.Text.__init__(self)
def write(self, message):
printout.insert(Tkinter.END, message)
printout = StdoutRedirector()
printout.pack()
sys.stdout = printout
root = Tkinter.Tk()
app = Application(root)
app.mainloop()
I'm new to coding, so I'll try the best I can =)
Quick answer:
You need to use .filename in the PIL object (Don't works on TK object)
#This is the image:
al_p4 = Image.open("Media/DVD/image.jpg").resize((100, 150), Image.ANTIALIAS)
#This is to show in Tkinter, Notice I added ..._TK
al_p4_TK = ImageTk.PhotoImage(al_p4)
#This is the filepath I think you want:
print(al_p4.filename)