How can I create a tkinter Python chat app with msg feature? - python

I want to create a Python chat app with msg feature.
Well, I've been working on this project for a while, and I want to build a messaging app using Python tkinter with msg feature available in any PC.
The problem is that the code contains some errors.
Now I will show you the code
from threading import *
from tkinter import *
import os
window = Tk()
window.title("msg")
window.geometry("350x150+300+100")
txtYourMessage = Entry(window, width=50)
txtYourMessage.insert(0,"")
txtYourMessage.grid(row=1, column=0, padx=10, pady=10)
server = Entry(window, width=50)
server.insert(0,"")
server.grid(row=2, column=0, padx=10, pady=10)
def Message():
os.system("msg * /server:%server% %txtYourMessage%")
btnSendMessage = Button(window, text="Send", width=20, command=Message)
btnSendMessage.grid(row=3, column=0, padx=10, pady=10)
window.mainloop()
When I run the code, the code actually works but it doesn't send the message you wrote, I think the problem is in this part
txtYourMessage = Entry(window, width=50)
txtYourMessage.insert(0,"")
txtYourMessage.grid(row=1, column=0, padx=10, pady=10)
server = Entry(window, width=50)
server.insert(0,"")
server.grid(row=2, column=0, padx=10, pady=10)
def Message():
os.system("msg * /server:%server% %txtYourMessage%")

correct code
from threading import *
from tkinter import *
import os
window = Tk()
window.title("msg")
window.geometry("350x150+300+100")
txtYourMessage = Entry(window, width=50)
txtYourMessage.insert(0,"")
txtYourMessage.grid(row=1, column=0, padx=10, pady=10)
server = Entry(window, width=50)
server.insert(0,"")
server.grid(row=2, column=0, padx=10, pady=10)
def Message():
os.system(f"msg * /server:{server.get()} {txtYourMessage.get()}")
btnSendMessage = Button(window, text="Send", width=20, command=Message)
btnSendMessage.grid(row=3, column=0, padx=10, pady=10)
window.mainloop()

Related

How do I fix this strange exception : Exception in Tkinter callback

I am working on a YouTube downloader project that takes a link and then puts the information about the video quality and sound quality of the link in the Combobox.
But when I try to put audio and video information in the Combobox, it gives this exception:
This is my code :
import tkinter
import tkinter.ttk
from tkinter import *
from tkinter import filedialog
from os import path
import pafy
from pafy import *
class Youtube():
def __init__(self):
self.label()
self.entry()
self.button()
self.combobox()
self.data=[]
def label(self):
Label(window, text='URL', font='bold').grid(row=0, column=0, padx=100)
Label(window, text='Destination', font='bold').grid(row=2, column=0, padx=100)
Label(window, text='File Name', font='bold').grid(row=4, column=0, padx=100)
Label(window, text='Video Quality', font='bold').grid(row=6, column=0, pady=20)
Label(window, text='Audio Quality', font='bold').grid(row=7, column=0, pady=5)
Label(window, text='Download Type', font='bold').grid(row=8, column=0, pady=15)
Label(window, text='Combine AV', font='bold').grid(row=8, column=1)
def entry(self):
global een
global en
en=Entry(window, width=35, borderwidth=10)
en.grid(row=1, column=0, padx=100, pady=5)
een=Entry(window, width=35, borderwidth=10)
een.grid(row=3, column=0, padx=100, pady=5)
Entry(window, width=35, borderwidth=10).grid(row=5, column=0, padx=100, pady=5)
def button(self):
Button(window, text='i', height=1, width=3, command=self.information).grid(row=1, column=1)
Button(window, text='d', height=1, width=3, command=self.destination).grid(row=3, column=1)
Button(window, text='Download', font='bold').grid(row=12, column=0, padx=150, pady=10, columnspan=3)
def combobox(self):
tkinter.ttk.Combobox(window, width=15).grid(row=6, column=1)
tkinter.ttk.Combobox(window, width=15).grid(row=7, column=1, pady=5)
tkinter.ttk.Combobox(window, values=['Audio only', 'Vido only', 'Audio and vido'],
width=15).grid(row=9, column=0)
tkinter.ttk.Combobox(window, values=['Yes', 'No'], width=15).grid(row=9, column=1, pady=20)
tkinter.ttk.Progressbar(window, orient=HORIZONTAL, length=300,
mode='determinate').grid(row=11, column=0, padx=200, pady=10, columnspan=3)
def destination(self):
path = str(filedialog.askdirectory())
een.insert(tkinter.END, path)
def information(self):
global link
link = en.get()
self.video()
self.audio()
def video(self):
video_quality_list = []
self.data = pafy.new(link)
video_streams = self.data.videostreams
for video_quality in video_streams:
video_quality_list.append(video_quality)
tkinter.ttk.Combobox(window, values=video_quality_list, width=15).grid(row=6, column=1, pady=5)
def audio(self):
audio_quality_list = []
self.data = pafy.new(link)
audio_streams = self.data.audiostreams
for audio_quality in audio_streams:
audio_quality_list.append(audio_quality)
tkinter.ttk.Combobox(window, values=audio_quality_list, width=15).grid(row=7, column=1)
window = Tk()
mywin = Youtube()
window.title('Youtube Downloader')
window.geometry("700x600+10+10")
window.mainloop()
I would be very grateful if anyone could help me to fix it.
Thanks!

How do I update my meter widget (python, ttkbootstrap) using the results I've gathered from a pyspeedtest?

I am trying to update my meter widget with the results of a ping test using pyspeedtest, but I keep getting the error:
"TypeError: Meter.configure() missing 1 required positional argument: 'self'"
The ping function works without any issues, I just can't seem to figure out how to pass the ping result to the meters "amountused" parameter to change the widget.
from tkinter import *
from tkinter.ttk import *
import ttkbootstrap as ttk
import pyspeedtest
root = Tk()
window = style.master
window_width = 300
window_height = 300
root.resizable(False, False)
ping_meter = ttk.Meter
ping_meter(
master=root,
metersize=300,
padding=20,
amountused=0,
metertype='semi',
subtext='milliseconds',
interactive=False
).grid(sticky=N, row=0, column=1, padx=10, pady=10)
myping = IntVar()
def ping_test():
t = pyspeedtest.SpeedTest(e1.get())
myping.set(t.ping())
ping_meter.configure(amountused = myping)
Label(root, text="Website URL:").grid(sticky=W, row=2, padx=10, pady=10)
Label(root, text="Ping Result:").grid(sticky=W, row=3, padx=10, pady=10)
result = Label(root, text="", textvariable=myping).grid(sticky=W, row=3, column=1, padx=10, pady=10)
e1 = Entry(root)
e1.grid(row=2, column=1)
b = Button(root, text="Check", command=ping_test)
b.grid(sticky=W, row=2, column=3, padx=10, pady=10)
mainloop()
the line ping_meter = ttk.Meter creates the variable ping_meter which is just the class ttk.Meter. therefore .configure() doesn't work. when you create an instance it isn't assigned to any variable, instead try doing this to create an instance of ttk.Meter, note that .grid() is called separately.
ping_meter = ttk.Meter(
master=root,
metersize=300,
padding=20,
amountused=0,
metertype='semi',
subtext='milliseconds',
interactive=False
)
ping_meter.grid(sticky=N, row=0, column=1, padx=10, pady=10)
also in ping_test() use ping_meter.configure(amountused = t) instead.

Using a Tkinter Widget from Lower Down in the Program

So I'm trying to make this tkinter GUI in which you can add or search for a customer (the customer is stored in a SQlite database). Problem is, I can't see a way of making the def for when the add customer button is pressed, for as far as I know, I would need to use the names of the variables from lower down in the program where the widgets are created. I could switch the order of the functions around, but then the widgets would be calling functions that have not already been created. Can someone help fix this probem? Thanks in advance.
Here's the code:
from tkinter import *
app = Tk()
app.minsize(400,420)
app.title("Gatecode Manager")
app.resizable(False, False)
def add():
first = createWindow().firstAdd.get()
last = createWindow().firstAdd.get()
phone = createWindow().numberAdd.get()
def createWindow():
Label(text="Welcome to Gatecode Manager", font=("bold", 17)).grid(row=0, columnspan=2, pady=30, sticky=N)
Label(text="Search for a Customer").grid(row=1, column=0, padx=30, pady=10)
Label(text="First Name:").grid(row=2, column=0, padx=30, pady=10)
firstSearch = Entry().grid(row=3, column=0, padx=30)
Label(text="Last Name:").grid(row=4, column=0, padx=30, pady=10)
lastSearch = Entry().grid(row=5, column=0, padx=30)
Label(text="Add Customer to System").grid(row=1, column=1, padx=30, pady=10)
Label(text="First Name:").grid(row=2, column=1, padx=30, pady=10)
firstAdd = Entry().grid(row=3, column=1, padx=30)
Label(text="Last Name:").grid(row=4, column=1, padx=30, pady=10)
lastAdd = Entry().grid(row=5, column=1, padx=30)
Label(text="Phone Number:").grid(row=6, column=1, padx=30, pady=10)
numberAdd = Entry().grid(row=7, column=1, padx=30)
add = Button(text="Add", command="null").grid(padx=30, pady=10, column=1)
app.mainloop()
createWindow()
I find it difficult to understand exactly how you want this program to function. Is the add button supposed to call the function add() which then calls createWindow()?
I'm guessing a little here but what about:
1) Don't create the GUI in a function. A function will keep the variables in the scope of the functioin.
2) Use StringVar() to access entries. Since you don't save the identity of your entries it becomes impossible to interrogate them.
Example:
from tkinter import *
app = Tk()
app.minsize(400,420)
app.title("Gatecode Manager")
app.resizable(False, False)
def add():
first = firstAddVar.get()
last = firstAddVar.get()
phone = numberAddVar.get()
Label(text="Welcome to Gatecode Manager", font=("bold", 17)).grid(row=0,
columnspan=2, pady=30, sticky=N)
Label(text="Search for a Customer").grid(row=1, column=0, padx=30, pady=10)
Label(text="First Name:").grid(row=2, column=0, padx=30, pady=10)
firstSearchVar = StringVar()
firstSearch = Entry(textvar=firstSearchVar).grid(row=3, column=0, padx=30)
Label(text="Last Name:").grid(row=4, column=0, padx=30, pady=10)
lastSearchVar = StringVar()
lastSearch = Entry(textvar=lastSearchVar).grid(row=5, column=0, padx=30)
Label(text="Add Customer to System").grid(row=1, column=1, padx=30, pady=10)
Label(text="First Name:").grid(row=2, column=1, padx=30, pady=10)
firstAddVar = StringVar()
firstAdd = Entry(textvariable=firstAddVar).grid(row=3, column=1, padx=30)
Label(text="Last Name:").grid(row=4, column=1, padx=30, pady=10)
lastAddVar = StringVar()
lastAdd = Entry(textvariable=lastAddVar).grid(row=5, column=1, padx=30)
Label(text="Phone Number:").grid(row=6, column=1, padx=30, pady=10)
numberAddVar = StringVar()
numberAdd = Entry(textvariable=numberAddVar).grid(row=7, column=1, padx=30)
add = Button(text="Add", command=add).grid(padx=30, pady=10, column=1)
app.mainloop()
When your GUIs become more complex you should study OOP.

Update Label in Tkinter when calling function

I have a Tkinter GUI and I would like to update the status of the script in a Label, writing which function is being called, but I am having problems with that.
I have already seen many answers on here, but still I cant come to a solution. This is the part of the code that I am working on:
run_script(username, password):
text = StringVar()
text.set('')
l=Label(master, text=text, fg='blue')
l.grid(row=6) #I would like the Label in the row 6
l.pack()
text.set('calling my function1')
my_file.my_function1(username, password)
text.set('calling my function2')
my_file.my_function2()
master = Tk()
username = Entry(master, name='username', width=30)
password = Entry(master, name='password', show='*', width=30)
username.grid(row=0, column=1, padx=10, pady=(10,2))
password.grid(row=1, column=1, padx=10, pady=2)
def call_report(username, password):
run_script(username, password)
Button(master, text='start script',
command= lambda:call_report(username.get(), password.get(),)).grid(row=6, column=1, sticky=W, pady=10)
mainloop()
The program run perfectly, just the label is not updated. Thanks
here is one way to do it, using the keyword argument textvariable:
import tkinter as tk
def run_script(username, password):
text = tk.StringVar()
text.set('')
lab = tk.Label(master, textvariable=text, fg='blue')
lab.grid(row=6)
text.set('calling my function1')
# call functions here
def call_report(username, password):
run_script(username, password)
if __name__ == '__main__':
master = tk.Tk()
username = tk.Entry(master, name='username', width=30)
password = tk.Entry(master, name='password', show='*', width=30)
username.grid(row=0, column=1, padx=10, pady=(10,2))
password.grid(row=1, column=1, padx=10, pady=2)
button = tk.Button(master, text='start script', command=lambda: call_report(username.get(), password.get(),))
button.grid(row=6, column=1, sticky=tk.W, pady=10)
master.mainloop()
Note:
The use of pack and grid geometry managers in the same widget is not encouraged.
Please import tkinter as tk: adding tk. is a small price to keep the namespace clean.
This is my solution that can be used as example:
from Tkinter import *
from time import sleep
def run_script():
text = StringVar()
l = Label(master, textvariable=text, fg='blue').grid(row=6)
text.set('calling my function1')
master.update()
sleep(2)
text.set('end of function1')
def call_report():
run_script()
if __name__ == '__main__':
master = Tk()
username = Entry(master, name='username', width=30)
password = Entry(master, name='password', show='*', width=30)
username.grid(row=0, column=1, padx=10, pady=(10,2))
password.grid(row=1, column=1, padx=10, pady=2)
button = Button(master, text='start script', command=lambda: call_report())
button.grid(row=6, column=1, sticky=W, pady=10)
master.mainloop()
I've changed text to textvariable in Label, and I added master.update(). In this way it force the GUI to redraw. Just to test if the GUI was changing, I tested with sleep. It is possible to update more time (for example before calling a function).

How to change the color of a Tkinter label programmatically?

I am trying to change the color of a Tkinter label when ever the user clicks the check button. I am having trouble writing the function correctly and connecting that to the command parameter.
Here is my code:
import Tkinter as tk
root = tk.Tk()
app = tk.Frame(root)
app.pack()
label = tk.Label(app, bg="white", pady=5, font=(None, 1), height=20, width=720)
checkbox = tk.Checkbutton(app, bg="white", command=DarkenLabel)
label.grid(row=0, column=0, sticky="ew")
checkbox.grid(row=0, column=0, sticky="w")
def DarkenLabel():
label.config(bg="gray")
root.mainloop()
Thank you
In your code, command=DarkenLabel is unable to find reference to the function DarkenLabel. Thus you need to define the function above that line, so you may use your code as following:
import Tkinter as tk
def DarkenLabel():
label.config(bg="gray")
root = tk.Tk()
app = tk.Frame(root)
app.pack()
label = tk.Label(app, bg="white", pady=5, font=(None, 1), height=20, width=720)
checkbox = tk.Checkbutton(app, bg="white", command=DarkenLabel)
label.grid(row=0, column=0, sticky="ew")
checkbox.grid(row=0, column=0, sticky="w")
root.mainloop()
Hope it helps!

Categories