Make a box and store the input in a variable tkinter - python

I'm trying to make a ping tool with a GUI on tkinter. The thing is that i would like to create a box where you could enter a web domain and then click ping and ping to that web. right now I have to change the web to ping on the code (V1.0) but i really tried to make the changes mentioned above but they don`t seem to work.
This is the original code:
#Imports
from subprocess import Popen, PIPE, STDOUT
import Tkinter as tk
from Tkinter import Tk
from threading import Thread
def create_worker(target):
return Thread(target=target)
def start_worker(worker):
worker.start()
#Ping printed on tkinter window root
def commande():
cmd = 'ping -c 10 google.com'
p = Popen(cmd.split(), stdout=PIPE, stderr=STDOUT)
for line in iter(p.stdout.readline, ''):
result.configure(text=line)
#tkinter code
root = Tk()
root.title('PingTool')
root.geometry('450x70+400+400')
worker = create_worker(commande)
tk.Button(root, text='Ping', command=lambda:start_worker(worker)).pack()
result = tk.Label(root)
result.pack()
root.mainloop()
One not working version:
from subprocess import Popen, PIPE, STDOUT
import Tkinter as tk
from Tkinter import Tk
from threading import Thread
#intput on the console
u = input('Website to ping: ')
def create_worker(target):
return Thread(target=target)
def start_worker(worker):
worker.start()
def commande():
cmd = 'ping -c 10 ' + u
p = Popen(cmd.split(), stdout=PIPE, stderr=STDOUT)#
for line in iter(p.stdout.readline, ''): #changes the text printed instead of printing multiple times
result.configure(text=line)#
root = Tk()
root.title('PingTool')
root.geometry('450x70+400+400')
worker = create_worker(commande)
tk.Button(root, text='Ping', command=lambda: start_worker(worker)).pack()
result = tk.Label(root)
result.pack()
root.mainloop()
The 'not working version' has the 'problem' that the input is written on the console. The idea is to create a label and input the text there.
I know this might not be the best place to ask something like this because it seems that i just want the work done but trust me I've really tried.
Thank you
PD: I'm starting with tkinter.

subprocess.check_output should be enough for what you want to do https://pymotw.com/2/subprocess/index.html#module-subprocess A simple program follows that runs the command when the button is pressed, and prints the output. I'll leave something for you to do, i.e. configure the text on a Label http://effbot.org/tkinterbook/label.htm and also you should add some code for an entry that is not a valid website.
import sys
if sys.version_info[0] < 3:
import Tkinter as tk ## Python 2.x
else:
import tkinter as tk ## Python 3.x
import subprocess
def button_callback():
ent_contents=ent.get()
output=subprocess.check_output("ping -c 10 "+ent_contents,
shell=True)
print "*****after", output, "\n"
root=tk.Tk()
ent=tk.Entry(root)
ent.grid(row=0, column=0)
ent.focus_set()
tk.Button(root, text="ping website", bg="lightblue",
command=button_callback).grid(row=1, column=0)
tk.Button(root, text="Exit Program", bg="orange",
command=root.quit).grid(row=2, column=0)
root.mainloop()

Related

Python tkinter button showing script to scrolledtext box

When i press the start button, it runs the other script but only shows it in the other terminal, not in the GUI scrolledtext box i have. is there a simple fix for my problem? not finding an answer anywhere.
from tkinter import *
from tkinter import ttk
from tkinter import filedialog
import sys
import os
import tkinter.scrolledtext as tkst
root = Tk()
root.title("WLP")
root.geometry("950x450")
root.iconbitmap("Vo1d.ico")
root.configure(bg='#0c0c0c')
def clickstart():
os.system('python WLP.py')
Button1 = Button(root, text="START", bg="#0c0c0c", fg="#C0C0C0", command=clickstart) #)
Textbox = tkst.ScrolledText(root, width=75, height=10, bg="#0c0c0c", fg="#C0C0C0")
Button1.grid(row=10, column=5, pady=15)
Textbox.grid(row=17, column=5)
root.mainloop()
This is far from a good way to do it, but this should work (after importing subprocess)
def clickstart():
output = subprocess.run(['python', 'WPL.py'], stdout=subprocess.PIPE, check=True)
output = str(output.stdout, encoding='utf-8')
Textbox.insert(1.0, output)

Perform multi-threading on a python program

I want to execute 2 function in the same time,
(im new in python, and development in general)
i tried to create a minecraft server setup assistant :
(the code is in development too)
import os
import tkinter as tk
from tkinter import ttk
import threading
import wget
import json
from pathlib import Path
...
def startndstop(x):
os.chdir(newpath)
if x == "start":
start = str("java" + ram() + namejar + " nogui")
print("Demarrage du serveur", name, "!")
os.system(str(start))
elif x == "stop":
os.system("stop")
root = tk.Tk()
root.title("Yann Installer")
root.iconbitmap("./minecraft_icon_132202.ico")
root.geometry("640x390")
root.resizable(width=False, height=False)
root.configure(bg="#0f800f")
bgimage = tk.PhotoImage(file="background.gif"))
l = tk.Label(root, image=bgimage)
l.pack()
installbutton = tk.Button(root, text="Installer", command=lambda :threading.Thread(target=install("1.8.3")).start())
installbutton.lift(aboveThis=l)
installbutton.place(x=10, y=10)
startbutton = tk.Button(root, text="Demarrer", command=lambda :threading.Thread(target=startndstop("start")).start())
startbutton.lift(aboveThis=l)
startbutton.place(x=10, y=40)
listeVersion = ttk.Combobox(root, values=versionlist())
listeVersion.current(0)
listeVersion.lift(aboveThis=l)
listeVersion.place(x=80, y=10, width=100)
threading.Thread(target=root.mainloop).start()
threading.Thread(target=startndstop,args=('start',)).start()
But when I execute the script , the second thread start only when i close the tkinter window.
edit: now the function are called correctly
Could you help me ?
Thread is not being called correctly. You are calling root.mainloop() and passing its return value to the threads as target, requiring it to run to completion in order to return. Instead, pass the function object itself as target by removing the parentheses. The second thread has the same issue, but needs to pass arguments as a separate args tuple.
Use this:
threading.Thread(target=root.mainloop).start() # start the tkinter interface
threading.Thread(target=startndstop,args=("start",)).start() # start the minecraft server

Tkinter threading and return to text widget

I've read some post on stack overflow,Issues intercepting subprocess output in real time, Redirect command line results to a tkinter GUI, i know i have to use threading and queue in tkinter, but I am still can't do the same thing because I am a beginner in program,please help.
The goal: When press a button, getting the 'top' command output and realtime display in tkinter text widget
The issue: I've tried to follow the code, but still cannot get the output, but I have not idea how to make it work.
from tkinter import *
import tkinter as tk
import subprocess
from threading import Thread
from queue import Queue
window = tk.Tk()
window.title('realtime')
window.geometry('800x400')
text = tk.Text(window)
text.pack()
button = tk.Button(window, text= 'Press')
button.pack()
window.mainloop()
This is only the gui outlook, please help
top refreshes itself now and then and I'm guessing that's the behavior you want to capture with threading and whatnot. However in this case it would be much easier to ask top to only run once, and have tkinter do the timing and refreshing:
import tkinter as tk
from sh import top
def update_text():
text.delete(0.0, tk.END)
text.insert(0.0, top('-b', n=1))
window.after(1000, update_text) # call this function again in 1 second
window = tk.Tk()
window.title('realtime')
window.geometry('800x400')
text = tk.Text(window)
text.pack()
button = tk.Button(window, text= 'Press', command=update_text)
button.pack()
window.mainloop()
You may need to install sh to run top like I did, or use subprocess.check_output if you want.
text.insert(0.0, subprocess.check_output(['top', '-b', '-n 1']))

Ping a website with output to Tkinter

I try to ping a website and display the output in real-time to a Label. Problem : the command makes an infinite loop (nom_mp4 = tk.Label(root, text=line) and the code stop before nom_mp4.pack().
Someone has an idea to make it work?
This is my code :
from subprocess import Popen, PIPE, STDOUT
import Tkinter as tk
from Tkinter import *
def commande():
cmd = 'ping www.wikipedia.com'
p = Popen(cmd.split(), stdout=PIPE, stderr=STDOUT)
for line in iter(p.stdout.readline,''):
nom_mp4 = tk.Label(root, text=line)
nom_mp4.pack()
root = Tk()
root.geometry('300x190+400+400')
browsebutton2 = tk.Button(root,text='Ping',command=commande) #le bouton browse
browsebutton2.pack()
root.mainloop()
One solution is to use threading.
from subprocess import Popen, PIPE, STDOUT
import Tkinter as tk
from Tkinter import Tk
from threading import Thread
def create_worker(target):
return Thread(target=target)
def start_worker(worker):
worker.start()
def commande():
cmd = 'ping www.wikipedia.com'
p = Popen(cmd.split(), stdout=PIPE, stderr=STDOUT)
for line in iter(p.stdout.readline, ''):
nom_mp4 = tk.Label(root, text=line)
nom_mp4.pack()
root = Tk()
root.geometry('300x190+400+400')
worker = create_worker(commande)
tk.Button(root, text='Ping', command=lambda: start_worker(worker)).pack()
root.mainloop()
cmd = 'ping www.wikipedia.com'
This will run infinite. You need to define how many times you want it to run. And maybe not ping a website when you are testing. For example:
cmd = 'ping -c 10 localhost'
-c 10 tells ping to run 10 times. localhost is just pinging your own machine, replace with URL when you have it working as intended.
You should also move the creation of the tk.Label outside of the for-loop. You don't need to create a new label each time, you just need to change the text value of the label. If you create and pack it after the tk.Button, it will appear below the button in the window.
To update the text of a tk.Label, you can do something like:
nom_mp4.configure(text=new_value_here)
The window will not be updated while the for-loop runs, and it will be "locked" until the loop has finished. To have it update you can put this at the end of the for-loop:
root.update_idletasks()
The window will still be locked though. To fix this I belive you will have to look into threading or something similar.
It works ! I have changed the code with your suggestions. I didn't put the -c option on the ping command because I wanted ping to work on its own without blocking the program. I changed the position of the pack outside of the loop as suggested by Oystein-hr and update the text with a configure. I also insert a threading with the example of Josh Leeb-du Toit.
Thanks guys.
from subprocess import Popen, PIPE, STDOUT
import Tkinter as tk
from Tkinter import Tk
from threading import Thread
def create_worker(target):
return Thread(target=target)
def start_worker(worker):
worker.start()
def commande():
cmd = 'ping localhost'
p = Popen(cmd.split(), stdout=PIPE, stderr=STDOUT)
for line in iter(p.stdout.readline, ''):
result.configure(text=line)
root = Tk()
root.geometry('600x80+400+400')
worker = create_worker(commande)
tk.Button(root, text='Ping', command=lambda: start_worker(worker)).pack()
result = tk.Label(root)
result.pack()
root.mainloop()

run a shell script from Python GUI

I've a GUI which will perform some functions when the buttons are pressed.
now i want to create a button in the GUI which will call and run a shell script in the background.
how can i achieve this ?
Not sure if your question is about how to call a shell script in Python, or how to make a button in your GUI. If the former, my comment above (recommending some research on subprocess.Popen) is the solution. Otherwise:
# assuming Python3
import tkinter as tk
import subprocess as sub
WINDOW_SIZE = "600x400"
root = tk.Tk()
root.geometry(WINDOW_SIZE)
tk.Button(root, text="Push me!", command=lambda: sub.call('path/to/script')).pack()
Python can run shell scripts using the supbprocess module. In order to run it in the background you can start it from a new thread.
To use the module
import subprocess
...
subprocess.call(['./yourScript.sh'])
For a good python threading resource you can try: How to use threading in Python?
Adding to what #lakesh said, below is the complete script :
import Tkinter
import subprocess
top = Tkinter.Tk()
def helloCallBack():
print "Below is the output from the shell script in terminal"
subprocess.call('./yourscript.sh', shell=True)
B = Tkinter.Button(top, text ="Hello", command = helloCallBack)
B.pack()
top.mainloop()
Please note that the shell script is in the same directory as that of the python script.
If needed, do chmod 777 yourscript.sh
subprocess.call('./yourscript.sh', shell=True)
and import Tkinter and not import tkinter solved the problems I was facing.
Use Tkinter to create a button. For more info, look at this video:http://www.youtube.com/watch?v=Qr60hWFyKHc
Example:
from Tkinter import *
root = Tk()
app = Frame(root)
app.grid()
button1 = Button(app,"Shell Script")
button1.grid()
root.mainloop()
To add the functionality:
change button1 line to:
button1 = Button(app,"Shell Script",command=runShellScript)
def runShellScript():
import subprocess
subprocess.call(['./yourScript.sh'])

Categories

Resources