TKinter Widget creation... Issue with arrangement of widgets - python-3.x

I was trying to create some nested widgets within file widget however exit is appearing above open. I tried changing the index but still the problems persists any idea how to fix this?
#!/usr/bin/python3
import tkinter as tk
import tkinter.ttk as ttk
from tkinter import messagebox
import sys
class GuiBaseClass():
def __init__(self,root):
# create widgets
self.root=root
root.title('GUIBASECLASS V0.1')
root.option_add('*tearOff', False)
self.menu=dict()
self.menubar = tk.Menu(root)
#File
menu_file = tk.Menu(self.menubar)
self.menubar.add_cascade(menu=menu_file,label='File',underline=0)
menu_file.add_separator()
menu_file.add_command(label='Exit', command=self.Exit,underline=0)
#Edit
menu_edit = tk.Menu(self.menubar)
self.menubar.add_cascade(menu=menu_edit,label='Edit',underline=0)
#Help
menu_help = tk.Menu(self.menubar)
menu_help.add_command(label='About', command=self.About, underline=0)
self.menubar.add_cascade(menu=menu_help,label ='Help',underline=0)
#config
root.config(menu=self.menubar)
self.menu['menubar'] = self.menubar
self.menu['File'] = menu_file
self.menu['Edit'] = menu_edit
self.menu['Help'] = menu_help
self.frame = ttk.Frame(root)
self.frame.pack(fill='both',expand=True)
# public functions
def mainLoop(self):
self.root.mainloop()
def getFrame(self):
return(self.frame)
def getMenu(self,entry):
if entry in self.menu:
return (self.menu[entry])
else:
# we create a new one
last = self.menu['menubar'].index('end')
self.menu[entry]= tk.Menu(self.menubar)
self.menu['menubar'].insert_cascade(
last, menu=self.menu[entry],label=entry)
return(self.menu[entry])
# private functions
def Exit(self,ask=True):
res = tk.messagebox.askyesno(title='Are you sure',message='Really quit the application')
if res:
sys.exit(0)
pass
def About(self):
print('print GUIBASECLASS V0.1')
if __name__ == '__main__':
root=tk.Tk()
bapp = GuiBaseClass(root)
# example for using the BaseClass in other applications
mnu=bapp.getMenu('Edit')
mnu.add_command(label='Copy',command=lambda: print('Copy'))
# example for using getFrame
frm=bapp.getFrame()
btn=ttk.Button(frm,text="Button X",command=lambda: sys.exit(0))
btn.pack()
bapp.mainLoop()
#!/usr/bin/python3
import tkinter as tk
import tkinter.ttk as ttk
from tkinter import filedialog
from tkinter import messagebox
from GuiBaseClass import GuiBaseClass
import os , sys
class PumlEditor(GuiBaseClass):
def __init__(self, root):
super().__init__(root)
# Create the File menu and add a "Open..." option
mnu_file = self.getMenu('File')
mnu_file.add_command(0, label='Open...', underline=0, command=self.fileOpen)
mnu_file.add_separator()
# Create the main text area
frame = self.getFrame()
#insert tk.Text
self.text = tk.Text(frame, wrap='word', undo=True)
self.text.insert('end', 'Hello start writing, please...')
self.text.delete('1.0','end')
self.text.pack(fill='both', expand=True)
def fileOpen(self, filename=''):
# Open a file dialog to select a file to open
if filename == "":
filename = filedialog.askopenfilename()
if filename != "":
self.text.delete('1.0','end')
file = open(filename,'r')
for line in file:
self.text.insert('end',line)
if __name__ == '__main__':
root = tk.Tk()
root.geometry("300x200")
pedit = PumlEditor(root)
# Create the PumlEditor instance and start the main loop
root.title("PumlEditor 2022")
if len(sys.argv)>1:
if os.path.exits(sys.arg[1]):
pedit.fileOpen(sys.argv[1])
pedit.mainLoop()
Open to appear before exit in files widget

Related

Tkinter Window too small

My kinter window is coming to small even after using geometry.
What to do so that it doesn't shrink?
Here's my code. And I can see the minimize button is coming towards left of the window. but I don't know ... why does this happen? I want to achieve oop for tkinter.
from logging import root
from tkinter import *
import tkinter as tk
from tkinter import messagebox
import mysql.connector
from tkinter import ttk
# from com.acc.report.database import
class Main(tk.Tk):
def __init__(self):
super().__init__()
# if not tasks:
# self.tasks = []
# instance of tkinter frame, i.e., Tk()
# root = Tk()
style = ttk.Style()
style.map("C.TButton",
foreground=[('pressed', 'red'), ('active', 'blue')],
background=[('pressed', '!disabled', 'black'), ('active', 'white')]
)
# width = self.winfo_screenwidth()
# height = self.winfo_screenheight()
self.geometry("626x431")
def selectReports():
messagebox.showinfo("EDP", "All reports")
def showReports():
messagebox.showinfo("EDP", "Select reports")
#Report Display Window
# def reviewReport():
# win = Toplevel(root)
# win.geometry("626x431")
monitor = ttk.Button(name="",text="Monitor",command=showReports,style="C.TButton")
review = ttk.Button(name="",text="Review",command=selectReports,style="C.TButton")
monitor.pack(pady=100)
review.pack(pady=0)
# Main method
if __name__ == "__main__":
objectMain = Main()
objectMain.withdraw()
objectMain.mainloop()
Make showReports and selectReports class methods, comment out or remove objectMain.withdraw() and everything should work.
from logging import root
from tkinter import *
import tkinter as tk
from tkinter import messagebox
#import mysql.connector
from tkinter import ttk
# from com.acc.report.database import
class Main(tk.Tk):
def __init__(self):
super().__init__()
self.geometry("626x431")
style = ttk.Style()
style.map("C.TButton",
foreground=[('pressed', 'red'), ('active', 'blue')],
background=[('pressed', '!disabled', 'black'), ('active', 'white')]
)
monitor = ttk.Button(name="",text="Monitor",command=self.showReports,style="C.TButton")
review = ttk.Button(name="",text="Review",command=self.selectReports,style="C.TButton")
monitor.pack(pady=100)
review.pack(pady=0)
def selectReports(self):
messagebox.showinfo("EDP", "All reports")
def showReports(self):
messagebox.showinfo("EDP", "Select reports")
# Main method
if __name__ == "__main__":
objectMain = Main()
# objectMain.withdraw()
objectMain.mainloop()

Reverting imported dictionary via QPushButton issues

I am having trouble understanding why a deep copy of a dictionary reverts back to original values when I run the revert() method once, but when I change values again, and run the revert() method again it changes the copied dictionaries values along with the original.
The dictionary/values are being imported from another file. I can only assume it is because the Test is being imported more than once.
Can someone help explain why this is happening and what can I do to avoid it?
Test.py
import ujson,copy
nested1 = {'1':None, '2':"String"}
nested2 = {'1':0.5123, '2':515}
diction = {'1':nested1, '2':nested2}
copyDiction = ujson.loads(ujson.dumps(diction))
copyOtherDiction = copy.deepcopy(diction)
Main.py
import Test
from PyQt5 import QtCore, QtWidgets, QtGui
class Window(QtWidgets.QMainWindow):
def __init__(self, parent = None):
super(Window,self).__init__(parent)
widget = QtWidgets.QWidget()
self.setCentralWidget(widget)
layout = QtWidgets.QVBoxLayout()
self.lineEdit = QtWidgets.QLineEdit()
self.button = QtWidgets.QPushButton("Change Value")
self.button.clicked.connect(self.changeMethod)
self.revertbutton = QtWidgets.QPushButton("Revert")
self.revertbutton.clicked.connect(self.revert)
layout.addWidget(self.lineEdit)
layout.addWidget(self.button)
layout.addWidget(self.revertbutton)
widget.setLayout(layout)
def changeMethod(self):
text = self.lineEdit.text()
if text.isdigit():
Test.diction['1']['2'] = int(text)
else:
Test.diction['1']['2'] = text
def revert(self):
print(Test.diction)
Test.diction = Test.copyDiction
print(Test.diction)
print(Test.copyDiction)
def main():
import sys
app = QtWidgets.QApplication(sys.argv)
window = Window()
window.show()
sys.exit(app.exec_())
if __name__ == "__main__":
main()

combining tkinter and watchdog

I'm trying the following
Create a GUI with tkinter where the user will choose a directory to watch
Close the window
Pass the path to the directory to watchdog so it can watch for file changes
How does one go about combining both scripts into one app ?
This below post has a script which does nothing when I add a *.jpg file to my temp folder (osx).
https://stackoverflow.com/a/41684432/11184726
Can someone point me towards a course or tutorial that will help me understand how to combine whats going on.
1. GUI :
from tkinter import *
from tkinter.filedialog import askopenfilename
from tkinter import filedialog
from tkinter.messagebox import showerror
globalPath = ""
class MyFrame(Frame):
def __init__(self):
Frame.__init__(self)
self.master.title("Example")
self.master.rowconfigure(5, weight=1)
self.master.columnconfigure(5, weight=1)
self.grid(sticky=W+E+N+S)
self.button = Button(self, text="Browse", command=self.load_file, width=10)
self.button.grid(row=1, column=0, sticky=W)
def load_file(self):
fname = askopenfilename(filetypes=(("Text File", "*.txt"),("All files", "*.*") ))
global globalPath
globalPath = fname
# fname = askopenfilename(filetypes=(("Text File", "*.txt"),("All files", "*.*") ))
if fname:
try:
print("""here it comes: self.settings["template"].set(fname)""")
print (fname)
except: # <- naked except is a bad idea
showerror("Open Source File", "Failed to read file\n'%s'" % fname)
return
if __name__ == "__main__":
MyFrame().mainloop() # All above code will run inside window
print(__name__)
print("the path to the file is : " + globalPath)
2. Watchdog :
from watchdog.observers import Observer
from watchdog.events import PatternMatchingEventHandler
def on_created(event):
# This function is called when a file is created
print(f"hey, {event.src_path} has been created!")
def on_deleted(event):
# This function is called when a file is deleted
print(f"what the f**k! Someone deleted {event.src_path}!")
def on_modified(event):
# This function is called when a file is modified
print(f"hey buddy, {event.src_path} has been modified")
#placeFile() #RUN THE FTP
def on_moved(event):
# This function is called when a file is moved
print(f"ok ok ok, someone moved {event.src_path} to {event.dest_path}")
if __name__ == "__main__":
# Create an event handler
patterns = "*" #watch for only these file types "*" = any file
ignore_patterns = ""
ignore_directories = False
case_sensitive = True
# Define what to do when some change occurs
my_event_handler = PatternMatchingEventHandler(patterns, ignore_patterns, ignore_directories, case_sensitive)
my_event_handler.on_created = on_created
my_event_handler.on_deleted = on_deleted
my_event_handler.on_modified = on_modified
my_event_handler.on_moved = on_moved
# Create an observer
path = "."
go_recursively = False # Will NOT scan sub directories for changes
my_observer = Observer()
my_observer.schedule(my_event_handler, path, recursive=go_recursively)
# Start the observer
my_observer.start()
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
my_observer.stop()
my_observer.join()
Below is the proposed sample code to merge the two scripts (not exactly copy the two scripts into one, but showing the concept of what you request):
from tkinter import *
from tkinter import filedialog
from watchdog.observers import Observer
from watchdog.events import PatternMatchingEventHandler
class Watchdog(PatternMatchingEventHandler, Observer):
def __init__(self, path='.', patterns='*', logfunc=print):
PatternMatchingEventHandler.__init__(self, patterns)
Observer.__init__(self)
self.schedule(self, path=path, recursive=False)
self.log = logfunc
def on_created(self, event):
# This function is called when a file is created
self.log(f"hey, {event.src_path} has been created!")
def on_deleted(self, event):
# This function is called when a file is deleted
self.log(f"what the f**k! Someone deleted {event.src_path}!")
def on_modified(self, event):
# This function is called when a file is modified
self.log(f"hey buddy, {event.src_path} has been modified")
def on_moved(self, event):
# This function is called when a file is moved
self.log(f"ok ok ok, someone moved {event.src_path} to {event.dest_path}")
class GUI:
def __init__(self):
self.watchdog = None
self.watch_path = '.'
self.root = Tk()
self.messagebox = Text(width=80, height=10)
self.messagebox.pack()
frm = Frame(self.root)
Button(frm, text='Browse', command=self.select_path).pack(side=LEFT)
Button(frm, text='Start Watchdog', command=self.start_watchdog).pack(side=RIGHT)
Button(frm, text='Stop Watchdog', command=self.stop_watchdog).pack(side=RIGHT)
frm.pack(fill=X, expand=1)
self.root.mainloop()
def start_watchdog(self):
if self.watchdog is None:
self.watchdog = Watchdog(path=self.watch_path, logfunc=self.log)
self.watchdog.start()
self.log('Watchdog started')
else:
self.log('Watchdog already started')
def stop_watchdog(self):
if self.watchdog:
self.watchdog.stop()
self.watchdog = None
self.log('Watchdog stopped')
else:
self.log('Watchdog is not running')
def select_path(self):
path = filedialog.askdirectory()
if path:
self.watch_path = path
self.log(f'Selected path: {path}')
def log(self, message):
self.messagebox.insert(END, f'{message}\n')
self.messagebox.see(END)
if __name__ == '__main__':
GUI()

Open a file with a button then storing the path in Python3

As the title states, I want to open a file with a browse button then store the file path for later use. I have no issue browsing the file, I just can't get the path to store into a variable. Many thanks.
from tkinter import *
from tkinter import filedialog
import openpyxl
from termcolor import cprint
# initializing tk
root = Tk()
root.title("Tools")
root.geometry("600x300")
frame = Frame(root)
frame.pack()
bottomframe = Frame(root)
bottomframe.pack(side = BOTTOM )
def getFile():
# open dialog box to select file
root.filename = filedialog.askopenfilename(initialdir="/", title="Select file")
#create button
browsebutton = Button(frame, text="Browse", command=getFile)
browsebutton.pack(side = BOTTOM)
#store the open file path into a variable
path = root.filename
You can use global(you should avoid global if possible) or use a class
def getfile():
path.set(filedialog.askopenfilename(initialdir="/", title="Select file")
def do_other_work_with_path():
#your Code here
print(path.get())
path = StringVar()
#using global
def getfile():
global path
path = filedialog.askopenfilename(initialdir="/", title="Select file")
# or using a class for your whole gui
from tkinter import *
from tkinter import filedialog
root = Tk()
class GUI:
def __init__(self, parent):
self.parent=parent
self.button=Button(self.parent, text='Browse', command=self.getfile)
self.button.pack()
def getfile(self):
self.path=filedialog.askopenfilename(initialdir="/", title="Select file")
gui=GUI(root)
#you can also call gui.path with a class
root.mainloop()

Using Tkinter and suprocess.call

I would like to use tkinter to open a window that will allow a user to select two separate files that will be manipulated several times within my script. I am having trouble finding a way to set the file that will be selected using the button in my tkinter window as a variable so that it can be used within subprocess.call. I have found invoke() but it doesn't seem to have any affect. Any ideas on what I might do would be greatly appreciated.
import os
import sys
import gdal
from gdalconst import *
import numpy as np
import math
import subprocess
from subprocess import call
import math
import datetime
import shutil
import tkinter
from tkinter import *
from tkinter import filedialog
newpath = os.path.expanduser('~\\Desktop\\Components\\Float32')
if not os.path.exists(newpath):
os.makedirs(newpath)
newpath_2 = os.path.expanduser('~\\Desktop\\Components\\Zeros')
if not os.path.exists(newpath_2):
os.makedirs(newpath_2)
newpath_3 = os.path.expanduser('~\\Desktop\\Components\\db_Files')
if not os.path.exists(newpath_3):
os.makedirs(newpath_3)
if __name__== '__main__':
# Set all of the necessary constants so that the script can create and save the pertinent files
# on the users desktop
#tk1 = Tk()
#tk2 = Tk()
#callTK = 'src_dataset =' + tk1
#callTK_2 = 'srcVH =' + tk2
gdalTranslate = 'C:\Program Files (x86)\GDAL\gdal_translate.exe'
tk1.fileName = filedialog.askopenfilename(text="Open HV File")
tk2.fileName = filedialog.askopenfilename(text="Open VH File")
dst_dataset = os.path.expanduser('~\\Desktop\\Components\\Float32\\newHV32.img')
dstVH = os.path.expanduser('~\\Desktop\\Components\\Float32\\newVH32.img')
sttime = datetime.datetime.now().strftime('(Time_Run = %Y-%d-%m_%H:%M:%S)')
wheel_install_1 = os.path.expanduser('~\\Desktop\\Components\\Sigma_Test\\wheel_install.py')
wheel_install_2 = os.path.expanduser('~\\Desktop\\Components\\Sigma_Test\\wheel_install2.py')
ridofz = os.path.expanduser('~\\Desktop\\Components\\Sigma_Test\\ridofZsv2.py')
to_dB = os.path.expanduser('~\\Desktop\\Components\\Sigma_Test\\to_dBv2.py')
db_HV = os.path.expanduser('~\\Desktop\\Components\\dB_Files\\newHVdB.img')
db_VH = os.path.expanduser('~\\Desktop\\Components\\dB_Files\\newVHdB.img')
cmd = "-ot float32 -of HFA" # hopefully this works
# Install necessary packages, which are GDAL and Numpy
# try:
#os.system(wheel_install_1)
#print ("GDAL intalled")
#os.system(wheel_install_2)
#print ("Numpy installed")
#except:
#print ("The packages are't installing properly")
#sys.exit()
# Create three new folders which will house the files that will be created
# along each sequential step of the script
#newpath = os.path.expanduser('~\\Desktop\\Components\\Float32')
#if not os.path.exists(newpath):
#os.makedirs(newpath)
#newpath_2 = os.path.expanduser('~\\Desktop\\Components\\Zeros')
#if not os.path.exists(newpath_2):
#os.makedirs(newpath_2)
#newpath_3 = os.path.expanduser('~\\Desktop\\Components\\db_Files')
#if not os.path.exists(newpath_3):
#os.makedirs(newpath_3)
root = Tk()
#root.fileName = filedialog.askopenfilename()
root.title("Utilis Sigma Test")
root.iconbitmap(r"C:\Users\jack.UTILIS\Desktop\images\sigma.ico")
root.configure(background="#179EBB")
topFrame = Frame(root)
topFrame.pack()
photo = PhotoImage(file="C:\\Users\\jack.UTILIS\\Desktop\\images\\Utilis_Branding2015_FINAL_Small.gif")
label = Label(root, image=photo)
label.pack(side=RIGHT)
bottomFrame = Frame(root)
bottomFrame.pack(side=BOTTOM)
button1 = Button(root, text="Open HV File", fg="black", command=filedialog.askopenfilename)
button2 = Button(root, text="Open VH FIle", fg="black", command=filedialog.askopenfilename)
button1.pack(side=LEFT)
button2.pack(side=RIGHT)
hvfullCmd = ' '.join([gdalTranslate, cmd, tk1.fileName,dst_dataset])
subprocess.call(hvfullCmd)
vhfullCmd = ' '.join([gdalTranslate,cmd, tk2.fileName,dstVH])
subprocess.call(vhfullCmd)
root.mainloop()
You have to create own function which get filename from askopenfilename and does something with this file. Then you can assign this file to button using command=
import tkinter as tk
from tkinter import filedialog
# --- functions ---
def on_click():
filename = filedialog.askopenfilename()
if filename:
print("Filename:", filename)
else:
print("Filename: not selected")
# --- main ---
root = tk.Tk()
btn = tk.Button(root, text='Click Me', command=on_click)
btn.pack()
root.mainloop()

Resources