I'm using tkinter for my python3 GUI. The script I wrote, when executing in IDLE. But when I try to execute it without the GUI is not responding.
Here's the code:
#! python3
from tkinter import *
import tkinter as tk
class Program:
nameC = ""
master = ""
varC = ""
def callback(self):
self.nameC= filedialog.askopenfilename()
def __init__(self):
self.master = Tk()
self.varC = StringVar(self.master)
l1 = Label(text="Open file", relief=RIDGE,width=15)
l1.grid(row=0,column=0)
b1 = Button(text='Open', command=self.callback)
b1.grid(row=0,column=1)
program = Program()
mainloop()
So far I have a button and a label. If I click on the button, a filedialog is opened using the callback function
EDIT: fixed one error in the code
If it helps, I'm using windows
So after running the script in the console ( as mentioned not IDLE) I figured out that I would have to import filedialog:
#! python3
from tkinter import *
from tkinter import filedialog # this is what I needed
import tkinter as tk
class Program:
nameC = ""
master = ""
varC = ""
def callback(self):
self.nameC= filedialog.askopenfilename()
def __init__(self):
self.master = Tk()
self.varC = StringVar(self.master)
l1 = Label(text="Open file", relief=RIDGE,width=15)
l1.grid(row=0,column=0)
b1 = Button(text='Open', command=self.callback)
b1.grid(row=0,column=1)
program = Program()
mainloop()
Related
PyQt5 App, I am building this app and had to use 2 .show(), 2 GUI show up when I run the code. One blank GUI and with with my information. When I remove the first .show() only the blank GUI shows up when I remove the second one nothing shows up any ideas.
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QWidget, QGridLayout, `enter code here`QLineEdit, QLabel
from PyQt5.QtWidgets import QPushButton, QVBoxLayout, QFormLayout, QPushButton, `enter code here`QTableWidget, QTableWidgetItem
from PyQt5.QtCore import Qt
import sqlite3
class ExerciseTracker(QWidget):
def __init__(self):
super().__init__()
self.myWindow = QWidget()
self.title = 'Exercise Tracker'
self.setWindowTitle(self.title)
self.setGeometry(200, 400, 300, 200)
self.move(60, 15)
self.layout = QFormLayout()
self.layout.addRow(QLabel('<h2>Welcome to the App!</h2>', parent=self.myWindow))
line_edit1 = QLineEdit()
self.layout.addRow('Day of the week: ', line_edit1)
line_edit2 = QLineEdit()
self.layout.addRow('Body Part: ', line_edit2)
line_edit3 = QLineEdit()
self.layout.addRow('Input Exercise: ', line_edit3)
line_edit4 = QLineEdit()
self.layout.addRow('Input Sets: ', line_edit4)
line_edit5 = QLineEdit()
self.layout.addRow('Input Reps: ', line_edit5)
btn1 = QPushButton('Submit')
self.layout.addRow(btn1)
btn2 = QPushButton('Show Records')
self.layout.addRow(btn2)
self.myWindow.setLayout(self.layout)
self.myWindow.show()
def main():
exercise = QApplication(sys.argv)
view = ExerciseTracker()
view.show()
sys.exit(exercise.exec_())
if __name__ =='__main__':
main()
I'm using Python's watchdog module to listen for created events on a certain directory. Where I do some processing on newly created .csv files. When I test my code with nothing in the handler the watchdog fires correctly for all pasted/created files, but when I add my code/logic inside the handler it fires less than expected (52/60 files for example).
OS used: Windows 10, code is expected to work on a Windows server.
Python version: 3.7.3
Code:
import time
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
import pandas as pd
import numpy as np
from error_handling import ErrorHandler
import os
from timeloop import Timeloop
from datetime import timedelta
import json
from fill_data import OnMyWatch2
class OnMyWatch:
# Set the directory on watch
watchDirectory = "."
def __init__(self):
self.observer1 = Observer()
def run(self):
self.observer1.schedule(Handler() , self.watchDirectory, recursive = True)
self.observer1.start()
try:
while True:
time.sleep(1)
except:
self.observer1.stop()
print("Observer Stopped")
self.observer1.join()
class Handler(FileSystemEventHandler):
#staticmethod
def on_any_event(event):
if event.is_directory:
return None
elif event.event_type == 'created':
try:
# Event is created, you can process it now
print("Watchdog received created event - % s." % event.src_path)
pathlower = str(event.src_path).lower()
if ".csv" in pathlower:
print("File is csv file")
# Once any code is added here the problem happens
# Example:
# df = pd.read_csv(event.src_path, names= ALL_INI.columnlistbundle.split("|"), sep="|", encoding='latin-1', engine='python')
# arraySelectedColumnsBundle = ALL_INI.selectedcolumnsbundle.split(",")
# bundle_df = df[np.array(arraySelectedColumnsBundle)]
else:
print("File is not csv file")
except Exception as e:
ErrorHandler(0, 'In Observer ', '-7', 'Exception ' + str(e), '', 1, '')
if __name__ == '__main__':
if os.path.isdir("."):
watch = OnMyWatch()
watch.run()
I created a basic Tkinter GUI that has one button that when you click on it, it is supposed to use multiprocessing in order to open up 5 Chrome instances of "https://www.google.com." When I compile the script using cx_freeze, I click on the new exe and the button does nothing. Here is the code:
main.py
from tkinter import *
from selenium import webdriver
import os, multiprocessing
import numpy as np
def func():
print("bot started")
home = "https://www.google.com"
chromeOptions = webdriver.ChromeOptions()
user_txt_path = []
user_txt_path.append('\\chromedriver.exe')
filename = os.path.dirname(sys.argv[0])
path_to_chromedriver = str(os.path.abspath(filename) + user_txt_path[0])
driver = webdriver.Chrome(chrome_options=chromeOptions, executable_path=path_to_chromedriver) #DRIVER DRIVER!
driver.get_cookies()
driver.get(home)
def callback():
num = 5
for n in np.arange(num):
p = multiprocessing.Process(target=func)
p.start()
master = Tk()
b = Button(master, text="OK", command=callback)
b.pack()
mainloop()
setup.py
from cx_Freeze import setup, Executable
import sys
import os
from pathlib import Path
user_txt_path = []
base = "Console"#"Win32GUI"
user_txt_path.append('chromedriver.exe')
import os.path
PYTHON_INSTALL_DIR = os.path.dirname(os.path.dirname(os.__file__))
os.environ['TCL_LIBRARY'] = os.path.join(PYTHON_INSTALL_DIR, 'tcl', 'tcl8.6')
os.environ['TK_LIBRARY'] = os.path.join(PYTHON_INSTALL_DIR, 'tcl', 'tk8.6')
buildOptions = {"include_files": [user_txt_path[0], 'tcl86t.dll', 'tk86t.dll'], "packages": ['encodings', "os"], "includes": ['numpy.core._methods', 'numpy.lib.format'], "excludes": []}
executables = [
Executable('main.py', base=base)
]
home_path = str(Path.home())
pathname = str(os.path.dirname(sys.argv[0]))
setup(name='numbers',
version = '1.0',
#description = 'test',
#shortcutName="TachySloth",
#shortcutDir="DesktopFolder",
options = dict(build_exe = buildOptions),
executables = executables
)
Note that you need all of the include_files in your parent directory with main.py.
As suggested here I use it to hide my command prompt in my setup.py file. It does hide my command prompt but the app does not work. Basically I am trying to make a Windows native Microsoft MSI for my GUI that I have built for youtube-dl command line tool that is used to consume media from some of the most popular video hosting sites. Any help is much appreciated. Here is my app.py:-
from tkinter import *
from tkinter import ttk
from tkinter import messagebox
from tkinter import filedialog
from tkinter.ttk import Progressbar
import youtube_dl
import threading
import os
download_folder = os.path.expanduser("~")+"/Downloads/"
download_folder_chosen = ""
window = Tk()
window.title("IOB Youtube Downloader")
window.geometry('510x100')
def my_hook(d):
if d:
if d['status'] == 'downloading':
percent_done = d['_percent_str']
percent_done = percent_done.replace(" ", "")
percent_done = percent_done.replace("%", "")
bar['value'] = percent_done
bar.grid(column=1, row=2, pady=15)
bar_lbl.configure(text=percent_done + "%")
bar_lbl.grid(column=1, row=3)
txt['state'] = DISABLED
btn['state'] = DISABLED
if d['status'] == 'finished':
bar.grid_forget()
txt['state'] = NORMAL
btn['state'] = NORMAL
bar_lbl.configure(text="Download Completed !!!")
bar_lbl.grid(column=1, row=2)
messagebox.showinfo('IOB Youtube Downloader', 'Download Complete')
if d['status'] == 'error':
print("\n"*10)
print(d)
messagebox.showerror('IOB Youtube Downloader', 'Download Error')
else:
bar_lbl.configure(text="Download Error. Please try again !!!")
bar_lbl.grid(column=1, row=2)
def start_thread():
t1 = threading.Thread(target=clicked, args=())
t1.start()
def clicked():
res = txt.get()
if download_folder_chosen != "":
location = download_folder_chosen + "/"
else:
location = download_folder
ydl_opts = {
'progress_hooks': [my_hook],
'format': 'best',
'outtmpl': location + u'%(title)s-%(id)s.%(ext)s',
}
try:
with youtube_dl.YoutubeDL(ydl_opts) as ydl:
ydl.download([res])
except:
messagebox.showerror('IOB Youtube Downloader', 'Download Error')
def choose_directory():
global download_folder_chosen
current_directory = filedialog.askdirectory()
download_folder_chosen = current_directory
messagebox.showinfo('IOB Youtube Downloader', 'Download Location:- ' + download_folder_chosen)
style = ttk.Style()
style.theme_use('default')
style.configure("blue.Horizontal.TProgressbar", background='blue')
bar = Progressbar(window, length=200, style='black.Horizontal.TProgressbar')
bar_lbl = Label(window, text="")
lbl = Label(window, text="Paste URL")
lbl.grid(column=0, row=0)
txt = Entry(window,width=60)
txt.grid(column=1, row=0)
btn = Button(window, text="Download", command=start_thread)
btn.grid(column=2, row=0)
btn2 = Button(window, text="...", command=choose_directory)
btn2.grid(column=3, row=0)
window.iconbitmap('favicon.ico')
window.mainloop()
And here is my setup.py file that I use to build the bundle exe using cx_Freeze.
from cx_Freeze import setup, Executable
import sys
import os
base = None
if sys.platform == 'win32':
base = "Win32GUI"
os.environ["TCL_LIBRARY"] = r"C:\Python35\tcl\tcl8.6"
os.environ["TK_LIBRARY"] = r"C:\Python35\tcl\tk8.6"
setup(
name = "IOB Youtube Downloader",
options = {"build_exe": {"packages":["tkinter",], "include_files":[r"C:\Python35\DLLs\tk86t.dll", r"C:\Python35\DLLs\tcl86t.dll", r"E:\Youtube_Downloader\Src\favicon.ico"]}},
version = "1.0",
author = "IO-Bridges",
description = "Download videos from all popular video streaming sites.",
executables = [Executable
(
r"downloader.py",
# base=base, <---- Here setting the base
shortcutName="IOB Youtube Downloader",
shortcutDir="DesktopFolder",
icon="favicon.ico"
)]
)
I have a chat window for the client portion of a chat application that uses Tkinter for the GUI:
import socket
import select
import time
from threading import Thread
from multiprocessing import Process
import sys
from tkinter import *
HOST = "localhost"
PORT = 5678
client_socket = socket.socket()
client_socket.settimeout(2)
try:
client_socket.connect((HOST, PORT))
except:
print("Connection failed.")
sys.exit()
print("Connected to [" + str(HOST) + "," + str(PORT) + "] successfully")
class ChatWindow:
def __init__(self):
form = Tk()
form.minsize(200, 200)
form.resizable(0, 0)
form.title("Chat")
box = Entry(form)
form.bind("<Return>", lambda x: self.sendmessage(self.textbox.get()))
area = Text(form, width=20, height=10)
area.config(state=DISABLED)
area.grid(row=0, column=1, padx=5, pady=5, sticky=W)
box.grid(row=1, column=1, padx=5, pady=5, sticky=W)
self.textbox = box
self.textarea = area
p1 = Process(target=updating)
p1.start()
p2 = Process(target=tryrecvmessage)
p2.start()
def addchat(self, msg, clear=False):
self.textarea.config(state=NORMAL)
self.textarea.insert(END, msg + "\n")
if clear:
# Option to clear text in box on adding
self.textbox.delete(0, END)
self.textarea.see(END)
self.textarea.config(state=DISABLED)
def sendmessage(self, msg):
data = str.encode(msg)
client_socket.send(data)
self.addchat("<You> " + msg, True)
def updating(self):
while True:
form.update()
form.update_idletasks()
time.sleep(0.01)
def tryrecvmessage(self):
while True:
read_sockets, write_sockets, error_sockets = select.select([client_socket], [], [])
for sock in read_sockets:
data = sock.recv(4096)
if data:
self.addchat(data)
else:
self.addchat("Disconnected...")
sys.exit()
if __name__ == "__main__":
window = ChatWindow()
I want the updating() function and the tryrecvmessage() function to run simultaneously, so that the GUI continues to update while the client still receives messages from the server. I've tried using the threading module as well, but I need to have the threads created below where the other functions are defined, but the other functions need to be defined below __init__(). What do I do?
You can attach the functions to the Tk event loop using the after method, as I explained in this question. Essentially the syntax for after goes like this:
after(ms, command = [function object])
What it does is attach the function object passed in as the command argument to the Tk event loop, repeating it each time ms milliseconds has passed.
One caveat here: you would want to remove the while True from the functions as after would be constantly repeating them anyway.