When I run this Tkinter application, and the submit button is clicked. What should happen is the combobox_window.py should run automatically, and a new Tkinter window should open. However, when do so I get the error:
'combobox_window.py' is not recognized as an internal or external command,
operable program or batch file.
I was using originally using Sublime Text to code, and had no problem with running thecombo_box.py file when the button was clicked. Today I have converted to PyCharm (easier to import libraries), so I am new to it.
Any suggestions?
file1.py
class Completion(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
def next_page():
os.system('combobox_window.py')
submit_button = tk.Button(self, text="Submit", command=next_page)
submit_button.pack()
combobox_window.py
import tkinter as tk
from tkinter import *
class SelectionWindow(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
combobox_values = ("Hello", "Goodbye")
combo = Combobox(state="readonly", values=combobox_values)
combo.pack()
if __name__ == "__main__":
app = SelectionWindow()
app.title("Selection Stage")
app.mainloop()
Related
I was wondering if there was a way to run the tkinter mainloop on a separate thread (not the mainthread) so that the terminal is "free".
Let's say we have a simple GUI:
import tkinter as tk
class Application(tk.Frame):
def __init__(self, master=None):
tk.Frame.__init__(self, master)
self.grid()
self.createWidgets()
def printHello(self):
print("Hello")
def createWidgets(self):
self.quitButton = tk.Button(self, text='Quit',
command=self.quit)
self.quitButton.grid(row=1,column=0)
self.printButton = tk.Button(self, text='Print',command=lambda: self.printHello())
self.printButton.grid(row=1,column=1)
app = Application()
app.master.title('Sample application')
app.mainloop()
Observed behavior: if I run this file using the terminal in PyCharm (let's say) using: python application.py, the terminal is then "frozen"/"occupied" by the tkinter mainloop and I am not able to type anything in the terminal.
Desired behavior: if I run the gui file with python application.py, the terminal is "free" such that it is able to take in additional commands.
I'm aware that python application.py & is supposed to free up the terminal but that hasn't worked for me. I'm not very experienced with threading or GUI processes but is there a way to run the tkinter mainloop in a different process / thread so that the terminal will be "free"?
You can use the threading module to run the GUI in a background thread while using the terminal in the main thread.
Try this code. It will start the GUI then allow input from the terminal.
import tkinter as tk
import threading
class Application(tk.Frame):
def __init__(self, master=None):
tk.Frame.__init__(self, master)
self.grid()
self.createWidgets()
def printHello(self):
print("Hello")
def createWidgets(self):
self.quitButton = tk.Button(self, text='Quit',
command=self.quit) # exits background (gui) thread
self.quitButton.grid(row=1,column=0)
self.printButton = tk.Button(self, text='Print',command=lambda: self.printHello())
self.printButton.grid(row=1,column=1)
def runtk(): # runs in background thread
app = Application()
app.master.title('Sample application')
app.mainloop()
thd = threading.Thread(target=runtk) # gui thread
thd.daemon = True # background thread will exit if main thread exits
thd.start() # start tk loop
while True: # run in main thread
x = input("Enter a value or Q to quit: ")
if x.lower() == 'q':
exit()
print('You entered', x)
There are some similar questions already on this site. The difference is that I'm coding the Tkinter window as a class. Then making an instance in another file. For example:
import file
gui = file.Window()
gui.mainloop()
# The program continues, using the variables chosen by the user in the previous window.
while file is another file that contains the window code:
import tkinter as tk
class Window(tk.Tk):
def __init__(self, master):
# some code
def mainWidgets(self):
self.body = Body(self)
self.body.grid(row=0, column=0)
class Body(tk.Frame):
def __init__(self, master):
tk.Frame.__init__(self, master)
self.master = master
self.widgets()
def widgets(self):
# Labels entries and selections
self.boton_enviar = tk.Button(self, text='Send', command=self.send)
self.boton_enviar.grid()
def send(self):
variables = self.variables
# What code do I add here?
self.quit()
So I want to close the window when clicking the 'Send' button but I need to retrieve some variables to use in the main program. How can I do this ?
I'm currently calling up a class from my robot framework script and it opens up two windows of Tkinter. I've tried running my python object via PyCharm and through the cmd and i only get one Tkinter window through that. However when i call my object through RobotFramework it opens up a blank Tk window and the expected Tk window. Any ideas?
My Hello.py is:
from Tkinter import *
class hello(object):
def __init__(self, question="Not today"):
self.question = question
self.master = Tk()
self.lbl = Label(self.master, text=self.question)
self.lbl.pack()
self.btn = Button(self.master, text="Yes", command=self.yes_command)
self.btn.pack()
self.master.mainloop()
def yes_command(self):
print("User pressed Yes")
self.master.quit()
self.master.destroy()
My tk_hello file contents are:
from Tkinter import *
class tk_hello(object):
def __init__(self, question):
self.question = question
self.master = Tk()
self.lbl = Label(self.master, text=self.question)
self.lbl.pack()
self.btn = Button(self.master, text="Yes", command=self.yes_command)
self.btn.pack()
self.master.mainloop()
def yes_command(self):
print("User pressed Yes")
self.master.quit()
self.master.destroy()
My Robot Framework script is:
*** Settings ***
Library hello.py
*** Variables ***
*** Test Cases ***
Example_1
Import Library ${CURDIR}\\..\\work_project\\tk_hello.py "Worked" WITH NAME Try_This
Log To Console \r ${CURDIR}
When you import Hello.py, robot detects a class named hello so it automatically instantiates it. It creates a root window in the __init__ function, so that's your first window.
When you import tk_hello.py, robot detects a class named tk_hello, so it automatically instantiates it. It creates a root window in the __init__ function, that's your second window.
I wrote a script in a .py file that I would like to call from another main file of my program. But when I do that, it does not initialize and give the same output as when runned directly.
here's the code of the main file where I import the subTest file as a module and call it when the user clicks on a button:
#!/usr/bin/python
import tkinter as tk
from tkinter import ttk
import subTest
from subTest import SubTest
class Window(tk.Tk):
def __init__(self, parent):
tk.Tk.__init__(self, parent)
tk.Tk.wm_title(self, "Test")
self.parent = parent
self.initialize()
def initialize(self):
self.geometry("600x300+30+30")
label = tk.Label(self, text="Test")
label.pack(pady=20,padx=10)
self.button = ttk.Button(self, text='gotosubtest', command = self.callsubtest)
self.button.pack()
def callsubtest(self):
app = SubTest(None)
app.mainloop()
if __name__ == "__main__":
window = Window(None)
window.mainloop()
and here's the code of the subTest file containing an Entry text box which should be initialized at 320. This is a simplified example of the problem. when subTest is executed directly, this Entry default value is shown in the text box. But when subTest is called from the main, the value is not shown.
Any idea what's wrong with my code? thanks in advance to all useful tips for a python beginner ;)
#!/usr/bin/python
import tkinter as tk
from tkinter import Entry
class SubTest(tk.Tk):
def __init__(self, parent):
tk.Tk.__init__(self, parent)
tk.Tk.wm_title(self, "SubTest")
self.parent = parent
self.initializesubtest()
def initializesubtest(self):
self.geometry("510x480")
self.minx = tk.DoubleVar()
self.minx.set(320)
Entry(self, textvariable=self.minx,width=5).grid(row=21,column=1)
tk.Label(self, text="Min X").grid(row=22,column=1)
if __name__ == "__main__":
app = SubTest(None)
app.mainloop()
You can only have a single instance of Tk in a program. When you use that other module you are creating a second root window. For you to be able to use that second module in the first, it cannot create its own root window.
I have a tkinter menu that lets the user choose some functions. I would like if the output of that functions was presented on a texbox in Tkinter instead of the Shell. Im very unexperienced with Tkinter. I donĀ“t have any ideia how to do it..
Some of the functions require inputs of the user, is it possible for the user to input directly from Tkinter Gui?
The code for the menu of the program:
the functions: situacaocorrente(), findfuncionario(), verhistorico() are not presented here.
CODE
from Tkinter import Tk, Frame, Menu, Label, Text
import sys
class Example(Frame):
def __init__(self, parent):
Frame.__init__(self, parent)
self.parent = parent
self.output = Text(self)
self.output.pack()
sys.stdout = self
self.initUI()
def initUI(self):
self.parent.title("High Flex")
menubar = Menu(self.parent)
self.parent.config(menu=menubar)
fileMenu = Menu(menubar)
fileMenu.add_command(label="Procurar funcionario", command=self.procurarfuncionario)
fileMenu.add_command(label="Ver Historico", command=self.historico)
fileMenu.add_command(label="Verificar Onde se encontram os funcionarios", command=self.funcionariosturno)
fileMenu.add_command(label="Sair", command=self.onExit)
menubar.add_cascade(label="INICIAR", menu=fileMenu)
def funcionariosturno(self):
situacaocorrente()
def procurarfuncionario(self):
findfuncionario()
def historico (self):
verhistorico()
def onExit(self):
self.quit()
def write(self, txt):
self.output.insert(END,str(txt))
def main():
root = Tk()
root.geometry("250x150+300+300")
app = Example(root)
root.mainloop()
You can use Entry() to get user input. See more on: An Introduction to Tkinter
I don't know what functions output you try to put in self.output - from external program in shell or from python function.
sys.stdout = self works only with Python functions like print