I'm very new Python coding and I'm having trouble linking my tkinter files, currently have 2 files 1 is the welcomescreen.py where user selects the form they wish to fill out, now I want user to go to the form they have selected do the activity and comebck to welcome, like press the quit button.
from tkinter import *
from tkinter import ttk
from tkinter import messagebox
class Feedback:
def __init__(self, master):
#CODING
#at the end
def main():
root = Tk()
feedback = Feedback(root)
root.mainloop()
if __name__ == "__main__":main()
and second file is something like this, actually i coded it pretty much in the same manner
from tkinter import *
from tkinter import ttk
from tkinter import messagebox
class Proj_pres:
"""Defininf clickable labels in frame"""
# CODES
# CODES
# at the end
def main():
root = Tk()
proj_pres = Proj_pres(root)
root.mainloop()
if __name__ == '__main__':main()
I tried the exec command but it didn't help.
Seems like all you need to do is import one of the script files you have in by the other one. Let's say you have the script file my_module1.py which has the widget class MyWidget1 and my_module2.py that has MyWidget2. Also the main part of your body should look like the following:
import my_module2
import tkinter as tk
...
if __name__ == '__main__':
root = tk.Tk()
welcome = MyWidget1(...)
welcome.quit_button['command'] = welcome.destroy
form = my_module2.MyWidget2(...)
root.mainloop()
Related
Good morning,
What I am aiming for:
I want to create a button that when clicked triggers a call back function (even if that function is still running).
Module:
I am using tkinter
Problem:
When I trigger the button, the function runs, but then I cannot push the button again before the function has finished its run. I want to be able to push the button while the function is still running and have the function stop and run again from start.
My attempts:
I tried both a procedural and a OOP approach: both present the same problem
My attempt n1: Procedural approach
import time
import tkinter as tk # Import tkinter
from tkinter import ttk # Import ttk
def func():
for i in range (100):
print(i)
time.sleep(5)
win = tk.Tk() # Create instance of the Tk class
aButton = ttk.Button(win, text="Click Me!", command=func)
aButton.grid(column=0, row=0) # Adding a Button
win.mainloop() # Start GUI
My attempt n2: OOP approach
import time
import tkinter as tk # Import tkinter
from tkinter import ttk # Import ttk
class OOP():
def func(self):
for i in range (100):
print(i)
time.sleep(5)
def __init__(self):
win = tk.Tk() # Create instance of the Tk class
aButton = ttk.Button(win, text="Click Me!", command=self.func)
aButton.grid(column=0, row=0) # Adding a Button
win.mainloop() # Start GUI
oop = OOP()
Thanks
In tkinter, as with most GUI frameworks, there is a for loop running somewhere that constantly checks for user input. You are hijacking that loop to do your func processing. Tkinter can not check for user input, nor e.g. change the appearance of the button icon, because there is only one thread and you are using it.
What you will want to do is fire up a thread or process to do the work. There are lots of libraries to do parallel processing in elaborate ways if you have lots of background tasks but this will do for a single function (see also this answer).
import time
import tkinter as tk # Import tkinter
from tkinter import ttk # Import ttk
import threading
def button():
thread = threading.Thread(target=func, args=args)
thread.start()
def func():
for i in range (100):
print(i)
time.sleep(5)
win = tk.Tk() # Create instance of the Tk class
aButton = ttk.Button(win, text="Click Me!", command=button)
aButton.grid(column=0, row=0) # Adding a Button
win.mainloop() # Start GUI
If the process is long running, you might need to find a way to clean up the threads when they're done.
I just need help in why this code does not work. I am unfamiliar with tkinter and this is the code that I was given and was told it should work. I see it says root is not defined but not sure what it should be defined as because I am assuming root is from tkinter? The only thing is that line 2 is grayed out. If you could help it would be greatly appreciated!
import tkinter as tk
from tkinter import *
class MyFirstGUI:
def __init__(self):
root.gui = tk.TK()
root.gui.title("A simple GUI")
root.gui.label = tk.Label(text="This is our first GUI!")
root.label.pack()
root.greet_button = tk.Button(text="Greet", command=self.greet)
root.greet_button.pack()
root.close_button = tk.Button(text="Close", command=self.gui.destroy)
root.close_button.pack()
def greet(root):
print("Greetings!")
root.mainloop()
my_gui = MyFirstGUI()
The identifier root is often assigned from tk.Tk(). If that's the case, then root will be the Tk application and the root of the Tk display graph.
You do all of your setup in the MyFirstGUI class's constructor, but you only use a local variable to keep track of the results. You therefore lose access to all of it when you exit the constructor.
I expect that you want to create everything as a root attribute on self so that your setup is encapsulated and preserved by the class.
Here's how I would rework your code to get it to do what I think you intend:
import tkinter as tk
from tkinter import *
class MyFirstGUI:
def __init__(self):
self.root = Tk()
self.root.title("A simple GUI")
self.root.label = tk.Label(text="This is our first GUI!")
self.root.label.pack()
self.root.greet_button = tk.Button(text="Greet", command=self.greet)
self.root.greet_button.pack()
self.root.close_button = tk.Button(text="Close", command=self.root.destroy)
self.root.close_button.pack()
def greet(root):
print("Greetings!")
my_gui = MyFirstGUI()
my_gui.root.mainloop()
This is a very simple version of my application. Basically I have a Tkinter application I want to start from another python application, but I do not have the option to have tkinter as my main window.
So my question is, if it's possible to pass some information from my main class to my tkinter application. Not once, but repeatedly.
I tried something like this, but this does not work, probably because of the .mainloop() method.
Right now I just try to print the variable "labelContent" whenever the button is pressed.
Is there some way I can pass information to my tkinter application after calling .mainloop() (besides using external files like .txt because this would obviously work)?
gui.py
import tkinter
class BasicWindow:
def __init__(self):
tk = tkinter.Tk()
label = tkinter.Label(tk, text="Hello World!")
label.pack()
self.labelContent = ""
button = tkinter.Button(tk,text="OK",command=self.buttonMethod)
button.pack(side="bottom")
tk.mainloop()
def buttonMethod(self):
print(self.labelContent)
main.py
from gui import BasicWindow
import time
class Main:
def __init__(self):
self.gui = BasicWindow()
self.gui.labelContent = "This is the new label content"
mainApp = Main()
while True:
mainApp.gui.labelContent = time.time()
Thanks in advance! :)
I want to make a Tkinter interface for a program I just wrote. The interface needs to have a widget where the user can insert an image for the program to process. I couldn't find such a widget online. How would I make such an interface?
Below is an example of tkinter entry widget that takes in images right away:
try: # In order to be able to import tkinter for
import tkinter as tk # either in python 2 or in python 3
import tkinter.filedialog as tkfd
except ImportError:
import Tkinter as tk
import tkFileDialog as tkfd
if __name__ == '__main__':
root = tk.Tk()
entry = tk.Entry(root)
entry.pack()
path = tkfd.askopenfilename(initialdir = "/", title = "Select file",
filetypes = (("jpeg files","*.jpg"),("all files","*.*")))
entry.insert('0', path)
root.mainloop()
im new topython 2.7 and want to know if it is possible to open a tkinter messagebox with a button combination on keyboard (Ctrl+alt+'something')
that pops up like an windows error message
import win32api
import time
import math
import Tkinter
import tkMessageBox
top = Tkinter.Tk()
def Message():
tkMessageBox.showinfo("Window", "Text")
for i in range(9000):
x = int(600+math.sin(math.pi*i/100)*500)
y = int(500+math.cos(i)*100)
win32api.SetCursorPos((x,y))
time.sleep(.01)
Yes, you can bind to control and alt characters. Bindings are fairly well documented. Here's one good source of information:
http://effbot.org/tkinterbook/tkinter-events-and-bindings.htm
As an example, to bind to ctrl-alt-x you would do this:
top.bind("<Control-Alt-x>", Message)
You can bind to a sequence of events by specifying the whole sequence. For example, if you wanted to implement a cheat code you could do something like this:
label.bind("<c><h><e><a><t>", Message)
For letters, "a" is the same as "<a>", so you can also do this:
label.bind("cheat", Message)
Here is a complete working example:
import Tkinter as tk
import tkMessageBox
def Message(event=None):
tkMessageBox.showinfo("Window", "Text")
def Cheat(event=None):
tkMessageBox.showinfo("Window", "Cheat Enabled!")
root = tk.Tk()
label = tk.Label(root, text="Press control-alt-m to see the messagebox\ntype 'cheat' to enable cheat.")
label.pack(fill="both", expand=True, padx=10, pady=100)
label.bind("<Control-Alt-x>", Message)
label.bind("<c><h><e><a><t>", Cheat)
label.focus_set()
root.mainloop()
If you want something like: Press button A, then press button B then open a Message box it is possible.
Do something like:
from Tkinter import *
import tkMessageBox
def change():
global switch
switch=True
def new_window():
if switch:
tkMessageBox.showinfo("Random name", "Correct combination")
else:
print "Not the correct order"
root = Tk()
switch = False
root.bind("<A>", change)
root.bind("<B>",new_window)
root.mainloop()
If you want more buttons then use an integer and increase it while using switches for the correct button order.
Note that you can bind key combinations as well with root.bind("<Shift-E>") for example
Edit: Now a and b keyboard button insted of tkinter buttons