Here is the code that i run in the python CMD:
import mailbox
import pprint
f = open("results.txt","w")
mbox = mailbox.mbox('c:\documents and settings\student\desktop\mail\mailall.mbox')
count = 0
for msg in mbox:
pprint.pprint(msg._headers, stream = f)
if msg['Delivered-To'] == 'example#example.co.uk':
count += 1
f.close()
print(count)
However when i run it in the GUI, it makes the GUI crash (Flashes black and doesn't open). Here is the GUI:
import datetime
from tkinter import filedialog
import tkinter
class App:
def __init__(self, master):
self.master = master
# call start to initialize to create the UI elemets
self.start()
def start(self):
self.master.title("Extract Email Headers")
self.now = datetime.datetime.now()
# CREATE A TEXT/LABEL
# create a variable with text
label01 = "Please select the .mbox file you would like to analyse"
# put "label01" in "self.master" which is the window/frame
# then, put in the first row (row=0) and in the 2nd column (column=1),
# align it to "West"/"W"
tkinter.Label(
self.master, text=label01).grid(row=0, column=0, sticky=tkinter.W)
# CREATE A TEXTBOX
self.filelocation = tkinter.Entry(self.master)
self.filelocation["width"] = 60
self.filelocation.focus_set()
self.filelocation.grid(row=1, column=0)
# CREATE A BUTTON WITH "ASK TO OPEN A FILE"
# see: def browse_file(self)
self.open_file = tkinter.Button(
self.master, text="Browse...", command=self.browse_file)
# put it beside the filelocation textbox
self.open_file.grid(row=1, column=1)
# now for a button
self.submit = tkinter.Button(
self.master, text="Execute!", command=self.start_processing,
fg="red")
self.submit.grid(row=3, column=0)
def start_processing(self):
import mailbox
import pprint
f = open("results.txt","w")
mbox = mailbox.mbox('c:\documents and settings\student\desktop\mail\mailall.mbox')
count = 0
for msg in mbox:
pprint.pprint(msg._headers, stream = f)
if msg['Delivered-To'] == 'example#example.co.uk':
count += 1
f.close()
print(count)
def browse_file(self):
# put the result in self.filename
self.filename = filedialog.askopenfilename(title="Open a file...")
# this will set the text of the self.filelocation
self.filelocation.insert(0, self.filename)
root = tkinter.Tk()
app = App(root)
root.mainloop()
If i take the process code out and put "pass", the GUI works so i know its the code that is throwing it off.? Thanks
Related
I made something in python to test my python skills. I tried converting it to an .EXE (the main python file itself) but it keeps starting itself over and over again: https://youtu.be/GItuZkD8nfo
it keeps starting new windows over & over again.
# Imports
from asyncio.log import logger
from asyncio.windows_events import NULL
from base64 import b64encode
from os import remove, mkdir
from shutil import rmtree
from shutil import move as movefile
from art import text2art
from anonfile import AnonFile
anon = AnonFile()
from discord_webhook import DiscordWebhook
from tkinter import NE, TOP, Entry, Label, Tk, Button, PhotoImage, messagebox, StringVar
import PyInstaller.__main__
from multiprocessing import freeze_support
freeze_support()
# Warn user to install python!
messagebox.showinfo("Python!", "Make sure you have python v3.10 installed before continuing")
# create temp folder
try:
mkdir('temp')
except FileExistsError:
pass
#labels / buttons to remove later
labels = []
#terminal art ;)
Art=text2art("Cappuccino")
print(Art)
#define GUI class
class MyFirstGUI:
def __init__(self, master):
self.master = master
#define title
master.title("Cappuccino")
#buttons
self.greet_button = Button(master, image=photo,highlightthickness=0, borderwidth=0,relief='flat',command=self.build)
self.quit = Button(master, image=quit_Image,highlightthickness=0, borderwidth=0,relief='flat', command=self.quit)
#pack the buttons
self.greet_button.pack(side="bottom")
self.quit.pack(side=TOP, anchor=NE)
#entry box
e1 = Entry(master, width=50, justify='center', textvariable=webhook)
e1.pack(padx=10, pady=100)
def quit(self):
#quit function
rmtree('temp')
exit()
def build(self):
#build function
for label in labels: label.destroy()
webhook_encoded = str(b64encode(webhook.get().encode('utf-8'))).replace("b'", "").replace("'", "")
try:
webhookSender = DiscordWebhook(url=webhook.get(), content='Cappucino Test!', username='Cappucino')
response = webhookSender.execute()
except:
print('ERROR! Most likely caused by: No internet connection or an invalid webhook!')
label = Label( root, image=error, highlightthickness=0, borderwidth=0,relief='flat' )
label.pack()
labels.append(label)
return
filename = anon.download("private", path='temp')
try:
f = open('temp/py1.py', 'r', encoding='utf-8')
except FileNotFoundError:
label = Label( root, image=error, highlightthickness=0, borderwidth=0,relief='flat' )
label.pack()
labels.append(label)
print('ERROR! Python file not found.')
return
code = f.read()
try:
l2 = open('temp/py2.py', 'w', encoding='utf-8')
except FileNotFoundError:
pass
l2.write(code.replace('Webhook_Here', webhook_encoded))
l2.close()
f.close()
error = False
try:
PyInstaller.__main__.run([
'temp/logger2.py',
'--onefile',
'--noconsole',
'--log-level=INFO',
'--icon=NONE',
])
except:
label = Label( root, image=error, highlightthickness=0, borderwidth=0,relief='flat' )
label.pack()
labels.append(label)
print('ERROR! PyInstaller failed converting the logger to an .EXE!')
return
movefile('dist/p2.exe', 'a.exe')
remove('logger2.spec')
try:
rmtree('temp/__pycache__')
rmtree('build')
rmtree('dist')
except OSError as e:
print("Error: %s - %s." % (e.filename, e.strerror))
remove('temp/py1.py')
remove('temp/py2.py')
#define root
root = Tk()
#define webhook
webhook = StringVar()
#configure background
root.configure(bg="#1e1e1e")
#configure icon
root.wm_iconbitmap('Cappuccino.ico')
#define window height and width
root.geometry("600x400")
#error text
photo = PhotoImage(file = "Untitled.png")
quit_Image = PhotoImage(file = "quit.png")
error = PhotoImage(file = "Error.png")
#gui?
my_gui = MyFirstGUI(root)
#loop
root.mainloop()
I tried adding
from multiprocessing import freeze_support
freeze_support()
but that did not work at all. I was expecting the program to work like normal.
Running the program from the normal .py file works just fine!
I want my display from the console to be displayed in a GUI (Tkinter). It should display exactly when it outputs to the Python console and not after the project is finished. Can you do this with Tkinter or are there other alternatives?
These are my current output. These should be shown on a gui in real Time.
Start program
iterations: [159]
Iteration 1 = complete
Iteration 2 = complete
.....
Iteration 159 = complete
lr 1.0
rc 1.0
rf 0.9966666666666667
gb 1.0
Training time: 8.76517425537s
Training finished
Process finished with exit code 0
You can do the following:
import sys
from tkinter import Tk, Button, Frame
from tkinter.scrolledtext import ScrolledText
class PrintLogger(object): # create file like object
def __init__(self, textbox): # pass reference to text widget
self.textbox = textbox # keep ref
def write(self, text):
self.textbox.configure(state="normal") # make field editable
self.textbox.insert("end", text) # write text to textbox
self.textbox.see("end") # scroll to end
self.textbox.configure(state="disabled") # make field readonly
def flush(self): # needed for file like object
pass
class MainGUI(Tk):
def __init__(self):
Tk.__init__(self)
self.root = Frame(self)
self.root.pack()
self.redirect_button = Button(self.root, text="Redirect console to widget", command=self.redirect_logging)
self.redirect_button.pack()
self.redirect_button = Button(self.root, text="Redirect console reset", command=self.reset_logging)
self.redirect_button.pack()
self.test_button = Button(self.root, text="Test Print", command=self.test_print)
self.test_button.pack()
self.log_widget = ScrolledText(self.root, height=4, width=120, font=("consolas", "8", "normal"))
self.log_widget.pack()
def reset_logging(self):
sys.stdout = sys.__stdout__
sys.stderr = sys.__stderr__
def test_print(self):
print("Am i working?")
def redirect_logging(self):
logger = PrintLogger(self.log_widget)
sys.stdout = logger
sys.stderr = logger
if __name__ == "__main__":
app = MainGUI()
app.mainloop()
I have two codes, one is "OK_Separating_testing_files.py" and the other "My_GUI.py".
After a lot of tries, finally I could make them work together.
First, I have my GUI "My_GUI.py"
#~~~~~~~~~~~~~~~~~~ Import required modules ~~~~~~~~~~~~~~~~~~#
from tkinter import messagebox, filedialog
from tkinter import *
from tkinter.ttk import *
import tkinter as tk
import Creating_testing_files
import subprocess
class ParentWindow(tk.Frame):
def __init__(self, master, *args, **kwargs):
Frame.__init__(self, master, *args, **kwargs)
self.master = master
self.master.maxsize(930, 450)
self.master.minsize(930, 450)
self.master.title("My Testing Tool")
arg = self.master
b = StringVar()
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Browse directory ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
def select_file():
my_file = filedialog.askopenfilename(initialdir=".", filetypes=[('Excel', ('*.xls', '*.xlsm', '*.xlsx')), ('CSV', '*.csv',)])
print(self.lab_file.insert(END, my_file))
self.lab_file = tk.Entry(self.master, textvariable=b, width=126, borderwidth=2, relief=tk.GROOVE)
self.lab_file.grid(row=2, column=1, sticky="EW")
self.btn_browse = tk.Button(self.master, highlightbackground='#333', text="Browse", command=select_file, width=8, font=("Arial", 9))
self.btn_browse.grid(row=2, column=0, padx=(65,0))
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Run button and message box ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
self.lab_run = tk.Label(self.master, font=("Arial", 10), text="Start the preparation: ")
self.lab_run.grid(row=9, column=0, sticky="E")
def run_script():
my_script = ['python', 'Creating_testing_files.py']
result1 = subprocess.Popen(my_script, stdin=subprocess.PIPE, stderr=subprocess.PIPE, stdout=subprocess.PIPE)
out1, err1 = result1.communicate()
status_wrapper = out1.decode("utf-8")
messagebox.showinfo("Processing", "Testing files are being processed!\n\nPlease close the tool's window.")
self.btn_run = tk.Button(self.master, highlightbackground='#333', text="Run", command=run_script, width=8, font=("Arial", 9))
self.btn_run.grid(row=9, column=1, sticky="NW")
def main():
main = tk.Tk()
app = ParentWindow(main)
main.mainloop()
#-------------------- Reference with main script --------------------#
def service_func():
print("")
if __name__ == '__main__':
service_func()
Creating_testing_files.some_func()
Then I have my main script "OK_Separating_testing_files.py" which is going to be executed after the user select the input Excel file.
#-------------------- Libraries --------------------#
import openpyxl
from openpyxl.worksheet.datavalidation import DataValidation
import My_GUI
My_GUI.main()
#-------------------- Opening network LLD file --------------------#
wb = openpyxl.load_workbook("HERE MUST BE THE USER INPUT FILE NAME")
#-------------------- Worksheets from network LLD file --------------------#
ws_conn = wb["sheet1"]
ws_old_fqdn = wb["FQDN"]
#-------------------- New files details --------------------#
#----- FQDNs file -----#
wb_fqdn = openpyxl.Workbook()
ws_fqdn_filter = wb_fqdn.create_sheet("Sheet", 1)
ws_fqdn_filter.title = 'Filters'
ws_fqdn = wb_fqdn['Sheet']
ws_fqdn.title = 'FQDNs'
#-------------------- Copying FQDNs values --------------------#
for row in ws_old_fqdn.rows:
for cell in row:
ws_fqdn[cell.coordinate] = cell.value
fqdn_cell = ws_fqdn[cell.coordinate]
#-------------------- Reference with GUI --------------------#
def some_func():
print("")
if __name__ == '__main__':
some_func()
What I am trying to do is use the user input Excel file in "My_GUI.py" code as the workbook my "OK_Separating_testing_files.py" is going to process in the line
wb = openpyxl.load_workbook("HERE MUST BE THE USER INPUT EXCEL FILE NAME")
At this point what I am doing is changing manually the name of the workbook to make it works, but I need it to be any workbook the user inputs and not making the user changing the code.
I hope this explanation is good enough.
Thanks a lot.
I am creating a GUI, where I have placed three buttons for selecting a file. When I click the button it browse for a file and display the selected file path and I am trying to do it with a single browse function since the operation is same. I am bit confused to how I should proceed . Can anyone please help me out.
Thanks in advance.
Here is my code:
Browse_Files.py
from tkinter import filedialog
def Browse_File():
global Bfilepath
Bfilepath = filedialog.askopenfilename(filetypes = (("Please select the required file", "*"), ("All files", "*")))
return Bfilepath
Main.py
from tkinter import *
import sys
import fileinput
import Browse_Files
root = Tk()
root.geometry('1400x800')
root.title('Dr Configuration')
Heading = Label(root, font=('Times New Roman',50,'bold'),text = "Arxml
Configuration Tool").place(x=300,y=25)
BasepathLabel = Label(root,font=('Times New Roman',20,'bold'),text = " Base
arxml").place(x=200,y=150)
NewpathLabel= Label(root,font=('Times New Roman',20,'bold'),text = "
New/Unedited arxml").place(x=200,y=250)
InterfaceLabel = Label(root,font=('Times New Roman',20,'bold'),text = "
Interface_File").place(x=200,y=350)
BpathtoDisp = StringVar(None)
BpathEntry = Entry(root,font=('Times New Roman',18),textvariable=
BpathtoDisp,justify='left',width=48).place(x=500,y=150)
NpathtoDisp = StringVar(None)
NpathEntry = Entry(root,font=('Times New Roman',18),textvariable=
NpathtoDisp,justify='left',width=48).place(x=500,y=250)
InterPathtoDisp = StringVar(None)
InterPathEntry = Entry(root,font=('Times New Roman',18),textvariable=
NpathtoDisp,justify='left',width=48).place(x=500,y=350)
button1 = Button(root,text="...",height=1,width=3,command=lambda:Browse_Files.Browse_File()).place(x=1100,y=150)
button2 = Button(root,text="...",height=1,width=3,command=lambda:Browse_Files.Browse_File()).place(x=1100,y=250)
button3 = Button(root,text="...",height=1,width=3,command=lambda:Browse_Files.Browse_File()).place(x=1100,y=350)
root.mainloop()
You could create a class that contains the functionality to have a button, open a file dialog, store it and make it available to other parts of the program.
I have a similar widget that I use in many different programs
from tkinter import *
from tkinter import filedialog
class FileSelect(Frame):
def __init__(self,master,label="",**kw):
Frame.__init__(self,master)
self.configure(**kw)
self.file = StringVar()
self.Label = Label(self, text=label)
self.Label.config(width=10,anchor=E)
self.filenamebox = Entry(self,text=self.file)
self.filenamebox.config(width=50)
self.btnBrowse = Button(self,text='Browse',command=self.browse_file)
self.btnBrowse.config(width=10)
self.Label.grid(row=0,column=0,pady=5,sticky=E)
self.filenamebox.grid(row=0,column=1,pady=5)
self.btnBrowse.grid(row=0,column=2,pady=5,padx=5)
def browse_file(self):
filename = filedialog.askopenfilename(filetypes=[('All File','*.*')])
self.file.set(filename)
def get_filename(self):
return self.file.get()
def main():
root = Tk()
root.title("Example Widget")
fileSelect1 = FileSelect(root,label="My File 1")
fileSelect1.grid()
fileSelect2 = FileSelect(root,label="My File 2")
fileSelect2.grid()
root.mainloop()
if __name__ == '__main__':
main()
In your code if you want the value of the file selected use
fileSelect1.get_filename()
EDIT: I've created a new version that is only a Button 'with memory' to remember which item was selected by the file dialog. This will allow you to place using the place geometry manager (which I don't recommend). Its not complete but you should get the idea.
from tkinter import *
from tkinter import filedialog
class FileSelectButton(Button):
def __init__(self,master,**kw):
Button.__init__(self,master,text='Browse',command=self.browse_file,width=10,**kw)
self.file = StringVar()
def browse_file(self):
filename = filedialog.askopenfilename(filetypes=[('All File','*.*')])
self.file.set(filename)
def get_filename(self):
return self.file.get()
def main():
root = Tk()
root.geometry('1400x800')
root.title("Example Widget")
Label(root, font=('Times New Roman',50,'bold'),text = "Label1").place(x=200,y=150)
fileSelect1 = FileSelectButton(root)
fileSelect1.place(x=500,y=150)
Label(root, font=('Times New Roman',50,'bold'),text = "Label2").place(x=200,y=250)
fileSelect2 = FileSelectButton(root)
fileSelect2.place(x=500,y=250)
root.mainloop()
if __name__ == '__main__':
main()
I have developed a simple app in Python (2.7) with Tkinter. But my status bar is only sort of working. Here's the stripped down code:
from Tkinter import *
import os
import sys
def fixFiles():
inputFilePath= input_dir.get()
#Build a list of files in a directory
fileList = os.listdir(inputFilePath)
#Loop through those files, open the file, do something, close the file
for filename in fileList:
infile = open(inputfilepath + "/" + filename,'r')
#Update the status with the filename
status_string = 'Status: Working on file: ' + str(filename)
status.set(status_string)
for line in infile:
#Do some stuff here
infile.close()
class App:
def __init__(self, master):
i = 0
status.set("Status: Press 'Fix Files!'")
statuslabel = Label(master, textvariable=status, relief = RIDGE, width = 65, pady = 5, anchor=W)
bFixFiles = Button(root, text='Fix Files!', command = fixFiles)
bQuit = Button(root, text='Quit', command = root.destroy)
statuslabel.grid(row=i, column = 0, columnspan = 2)
bFixFiles.grid(row=i, column=2, sticky=E)
bQuit.grid(row=i, column=3, sticky=W)
root = Tk()
root.title("FIX Files")
input_dir = StringVar()
status = StringVar()
choice = IntVar()
app = App(root)
root.mainloop()
Currently what's happening is that the status bar reads "Status: Press 'Fix Files!'" until the program is finished looping through the files, at which point it reads "Status: Working on file: XXXXX.txt" (which is the name of the last file to be opened and closed by the program.
I would like the status bar to update with the file name each time the program opens a new file. Any help is appreciated!
The goofy way is to use root.update_idletasks():
#Update the status with the filename
status_string = 'Status: Working on file: ' + str(filename)
status.set(status_string)
root.update_idletasks()
To its credit, it is simple, but it does not really work -- although the statuslabel gets updated, the Quit button is frozen until fixFiles is completed. That's not very GUI-friendly. Here are some more reasons why update and update_idletasks are considered harmful.
So how should we run a long-running task without freezing the GUI?
The key is to make your callback functions end quickly. Instead of having a long-running for-loop, make a function that runs through the innards of the for-loop once. Hopefully that ends quickly enough for the user to not feel the GUI has been frozen.
Then, to replace the for-loop, you could use calls to root.after to call your quick-running function multiple times.
from Tkinter import *
import tkFileDialog
import os
import sys
import time
def startFixFiles():
inputFilePath = tkFileDialog.askdirectory()
# inputFilePath= input_dir.get()
# Build a list of files in a directory
fileList = os.listdir(inputFilePath)
def fixFiles():
try:
filename = fileList.pop()
except IndexError:
return
try:
with open(os.path.join(inputFilePath, filename), 'r') as infile:
# Update the status with the filename
status_string = 'Status: Working on file: ' + str(filename)
status.set(status_string)
for line in infile:
# Do some stuff here
pass
except IOError:
# You might get here if file is unreadable, you don't have read permission,
# or the file might be a directory...
pass
root.after(250, fixFiles)
root.after(10, fixFiles)
class App:
def __init__(self, master):
i = 0
status.set("Status: Press 'Fix Files!'")
statuslabel = Label(
master, textvariable=status, relief=RIDGE, width=65,
pady=5, anchor=W)
bFixFiles = Button(root, text='Fix Files!', command=startFixFiles)
bQuit = Button(root, text='Quit', command=root.destroy)
statuslabel.grid(row=i, column=0, columnspan=2)
bFixFiles.grid(row=i, column=2, sticky=E)
bQuit.grid(row=i, column=3, sticky=W)
root = Tk()
root.title("FIX Files")
input_dir = StringVar()
status = StringVar()
choice = IntVar()
app = App(root)
root.mainloop()
The above begs the question, What should we do if our long-running task has no loop? or if even one pass through the loop requires a long time?
Here is a way to run the long-running task in a separate process (or thread), and have it communicate information through a queue which the main process can periodically poll (using root.after) to update the GUI status bar. I think this design is more easily applicable to this problem in general since it does not require you to break apart the for-loop.
Note carefully that all Tkinter GUI-related function calls must occur from a single thread. That is why the long-running process simply sends strings through the queue instead of trying to call status.set directly.
import Tkinter as tk
import multiprocessing as mp
import tkFileDialog
import os
import Queue
sentinel = None
def long_running_worker(inputFilePath, outqueue):
# Build a list of files in a directory
fileList = os.listdir(inputFilePath)
for filename in fileList:
try:
with open(os.path.join(inputFilePath, filename), 'r') as infile:
# Update the status with the filename
status_string = 'Status: Working on file: ' + str(filename)
outqueue.put(status_string)
for line in infile:
# Do some stuff here
pass
except IOError:
# You might get here if file is unreadable, you don't have read permission,
# or the file might be a directory...
pass
# Put the sentinel in the queue to tell update_status to end
outqueue.put(sentinel)
class App(object):
def __init__(self, master):
self.status = tk.StringVar()
self.status.set("Status: Press 'Fix Files!'")
self.statuslabel = tk.Label(
master, textvariable=self.status, relief=tk.RIDGE, width=65,
pady=5, anchor='w')
bFixFiles = tk.Button(root, text='Fix Files!', command=self.startFixFiles)
bQuit = tk.Button(root, text='Quit', command=root.destroy)
self.statuslabel.grid(row=1, column=0, columnspan=2)
bFixFiles.grid(row=0, column=0, sticky='e')
bQuit.grid(row=0, column=1, sticky='e')
def update_status(self, outqueue):
try:
status_string = outqueue.get_nowait()
if status_string is not sentinel:
self.status.set(status_string)
root.after(250, self.update_status, outqueue)
else:
# By not calling root.after here, we allow update_status to truly end
pass
except Queue.Empty:
root.after(250, self.update_status, outqueue)
def startFixFiles(self):
inputFilePath = tkFileDialog.askdirectory()
# Start long running process
outqueue = mp.Queue()
proc = mp.Process(target=long_running_worker, args=(inputFilePath, outqueue))
proc.daemon = True
proc.start()
# Start a function to check a queue for GUI-related updates
root.after(250, self.update_status, outqueue)
root = tk.Tk()
root.title("FIX Files")
app = App(root)
root.mainloop()