Tkinter window opens after code is finished - python

I'm just beginning to get the basic funtions of the soundcard python module to work. However I cannot make my tkinter window show up first and wait until I press the run button to exicute the "def run()" code. It always does the "def run()" code first and then opens the window. What am I doing wrong?
from tkinter import *
import soundcard as sc
window = Tk()
window.geometry("500x500")
window.title("Virtual Soundcard")
default_speaker = sc.default_speaker()
default_mic = sc.default_microphone()
def run():
with default_mic.recorder(samplerate=44100) as mic, \
default_speaker.player(samplerate=44100) as sp:
for val in range(100):
data = mic.record(numframes=None)
sp.play(data)
RunButton = Button(window, text ="Run", command = run())
RunButton.pack()
RunButton.place(x = 100, y = 250)
window.mainloop()

Change RunButton = Button(window, text ="Run", command = run()) to
RunButton = Button(window, text ="Run", command = run)
Basically remove the () for the command argument, with the () your calling the function even before pressing the button, ie, while code execution.
Hope this solved the error. Do let me know if any doubts or errors.
Cheers

Related

Exit button doesnt work after executeing ping command but does before doing so (tkinter)

So im very new to python and I'm basically trying to make a program were the user inputs a targets IP and then presses a button below to Execute the command (start the pinging process) and this I've done successfully but now I wanted to add an exit button below to stop the pinging process but I've got a problem. The button works fine before you press execute (works as intended it closes the application window) but when the script is running the button doesn't work at all and just kinda crashes the window but keeps the command running. How can I make the button work att all times (make it work when the script is running).
import tkinter as tk #import tkinter and tkinter library
from tkinter import ttk #package to style widget
import subprocess
def window(): #runs the window ??? i think
#address = input("Enter Ip Here:")
subprocess.call(f"ping {text.get()} -t -l 65500")
# root window
root = tk.Tk() # root?
root.geometry('200x200') #window size
root.resizable(False, False) # makes window non rezisable
root.title('Ping Of Death') #window title
var = tk.StringVar #variable tkinter = StringVar
text = tk.Entry(root,textvariable=var, width = 25)
text.pack()
# execute button
execute_button = ttk.Button( #defines the execute button
root,
text='Execute', #defines the text on the button
command=window
)
execute_button.pack( #package for button
ipadx=5, #x size
ipady=5, #y size
expand=True # ???
)
exit_button = ttk.Button(
root, text="Exit" ,
command=root.quit
)
exit_button.pack(pady=20)
root.mainloop() #to keep everything in a loop
I'm pretty sure that subprocess.call is blocking, so search on "subprocess.call non-blocking" and asyncio as an alternative.

Why is my tkinter program exiting shortly after it's started?

I've started learning Tkinter(some of you may know why). So I made a simple program by following a tutorial:
from tkinter import *
root = Tk()
myLabel1 = Label(root, text = "Hello Mushroom world!")
myLabel2 = Label(root, text = "Hello Mario world!")
myLabel1.grid(row = 0, column = 0)
myLabel2.grid(row = 1, column = 0)
root.mainloop()
When I runed it, it showed me a blank window for less than a second and then it disappears (by the way, the window was as big as a restore down window but I think it was supposed to be small because I didn't specify the size of the window). I'm on Windows 10 using WSL2 and I run my code on command prompt because it's a GUI. I would like to know what is causing this bug. Thanks!
You can add a button that destroys the window, therefore quits the App.
from tkinter import *
root = Tk()
def close_window():
root.destroy()
myLabel1 = Label(root, text = "Hello Mushroom world!")
myLabel2 = Label(root, text = "Hello Mario world!")
button = Button (text = "Close", command = close_window)
myLabel1.grid(row = 0, column = 0)
myLabel2.grid(row = 1, column = 0)
button.grid(row = 2, column = 0)
root.mainloop()
You can simplify by instead of using the close_window function, just type root.destroy for the command parameter.
EDIT
After editing the original question, it turns out the OP's program quit after ~a second, and he wanted to know why does that happen, instead of another way to quit. The error seems to be in his environment. After changing to the original python IDE/IDLE, the code works fine.
Turns out he named his file tkinter.py, that caused the bug.

How do I redirect output of a script to a tkinter window?

I am trying to click a tkinter button to open up a new tkinter window to execute a script within it all the way up to the end with a scroll bar if necessary. However, I have only succeeded this far in getting it to run in multitude of ways in a linux window and not within a tkinter window. Can someone help me with redirecting the output of this script into the toplevel window?
self.button_run = Button(self, text="RUN", width=16, command=self.callpy)
self.button_run.grid(row=25, column=0, columnspan=2, sticky=(W + E + N + S))
def run_robbot(self):
new = Toplevel(self)
new.geometry('500x200')
label = Message(new, textvariable=self.callpy, relief=RAISED)
label.pack()
def callpy(self):
pyprog = 'check_asim.robot'
call(['robot', pyprog])
In the snippet above, if I pass callpy to command in Button it runs the robot script in a linux window. If I replace it to call run_robbot which is what I want and expect, it just pops up a new window with a Message Box without running the same script passed to textvariable. I have tried Enter in place of Message Box as well.
I want callpy to be executed in Toplevel tkinter window at the click of the button. How do I do it? Any tkinter operator is fine as long as it confines to the tkinter window.
If you want to capture the output of the command, you should use subprocess.run(cmd,capture_output=True) instead. Below is an sample code:
import subprocess
from tkinter import *
class App(Tk):
def __init__(self):
Tk.__init__(self)
Button(self, text='Run', command=self.run_robot).pack()
def run_robot(self):
win = Toplevel(self)
win.wm_attributes('-topmost', True)
output = Text(win, width=80, height=20)
output.pack()
output.insert(END, 'Running ....')
output.update()
result = self.callpy()
output.delete(1.0, END)
output.insert(END, result)
def callpy(self):
pyprog = 'check_asim.robot'
return subprocess.run(['robot', pyprog], capture_output=True).stdout
App().mainloop()

How to make this script run in the background and listen for a "copy" action?

The script below does is if I copy a link like this: http://urlshortener.io/s/1234rIHs/?s=https%3A%2F%2Fexample.com%2Fsome_content%2F, it will change to
example.com/some_content/ if I clicked the button.
Is there a way that when I run this script then it will listen in the background for a "copy" action, and then if I copy some text in my browser, it will automatically slice the text I just copied and I won't need to click the button?
Right now, I still have to click the button in order for the slicing to happen.
from tkinter import *
from urllib import parse
from tkinter import Tk
root = Tk()
root.title("Slicer")
root.geometry('304x70')
lbl = Label(root, text="Link")
lbl.pack()
def clicked():
clip = root.clipboard_get()
clip = parse.unquote(clip)[45:]
root.clipboard_clear()
root.clipboard_append(clip)
lbl.configure(text= clip)
btn = Button(root, text="Slice", command=clicked, height = 3, width = 40)
btn.pack()
root.mainloop()
You can use pyperclip. Run an infinite loop, keep detecting for urls in the loop, modify when found.
import pyperclip, time
# Modify is_url and modify_url, according to your need
def is_url(s):
return True
def modify_url(url_string):
return "Hello World"
while True:
on_clip = pyperclip.paste()
if is_url(on_clip):
pyperclip.copy(modify_url(on_clip))
time.sleep(0.1)

No errors but wont run

So I have this code:
try:
# for Python2
from Tkinter import *
except ImportError:
# for Python3
from tkinter import *
class Injector():
def __openInjector(self):
root = Tk()
root.geometry('600x400')
root.title('Toontown Rewritten Injector')
root.resizable(False, False)
def __init__(self):
self.code = ''
self.__openInjector()
def runInjectorCode(self):
exec(self.code.get(1.0, 'end'), globals())
def __openInjector(self):
root = Tk()
root.geometry('600x400')
root.title('Toontown Rewritten Injector')
root.resizable(False, False)
frame = Frame(root)
self.code = Text(frame, width=70, height=20)
self.code.pack(side='left')
Button(root, text='Inject!', command=self.runInjectorCode).pack()
scroll = Scrollbar(frame)
scroll.pack(fill='y', side='right')
scroll.config(command=self.code.yview)
self.code.config(yscrollcommand=scroll.set)
frame.pack(fill='y')
Injector()
In the IDLE console it works fine and does everthing I want it to do. But whenever I run the .py file on my Desktop. The black window appears, then just closes and nothing happens. Any help?
First, you have two methods in your class with the same name. The first one gets overwritten by the second one. At the end of that second one, you need the following line:
root.mainloop()
This will actually run the GUI. It's needed when running from a script, but not when running within the interactive interpreter.
Add it at the end of the second __openInjector:
...
self.code.config(yscrollcommand=scroll.set)
frame.pack(fill='y')
root.mainloop()
At the end of your second __openInjector method, add the line: root.mainloop().
This is necessary for Tkinter to run your code. mainloop is really nothing more than an infinite loop that waits for events. An event may be a user interaction, such as clicking a button.
My guess is you don't need mainloop when running interactively for purely convenience reasons.

Categories