Reputation: 21
I have made a simple python program for a friend of mine that makes use of tkinter
and SMTPlib
.
I used pyinstaller
to make an .exe for the program, but when I double click the .exe my CMD terminal will flash on the screen for a split second than disappear. When I drag that same .exe to my CMD terminal and press enter, the program runs with no issues, every feature of the program works.
I am attaching my .spec file that pyinstaller
created, I have not modified it at all. I really feel like it should work, given that it 100% works if I call it from the CMD, only issues are when I double-click on the .exe. Extremely frustrating.
I have seen this same issue posted online several times, and there is no solution I have seen that has helped me. Any help would be greatly appreciated.
EDIT: Following the advice below I was able to get the program to run. I had to change the .spec file, specifically the datas
field in order to get it to work. However I am now having a problem where the .txt files will load, but upon editing them the edits are not saved as they should be. The edits were all being saved BEFORE I fixed the original issue, when I was only able to run the program from the CMD. I am posting the entire script below:
EDIT II: I had not put the files into 'w' mode, and this is why I wasn't getting any output to the text files. All is working now!
My spec file:
block_cipher = None
a = Analysis(['test.py'],
pathex=['C:\\Users\\wiley\\PycharmProjects\\EmailBot\\email_bot2'],
binaries=[],
datas=[('students1.txt', '.'),('students2.txt','.')],
hiddenimports=[],
hookspath=[],
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False)
pyz = PYZ(a.pure, a.zipped_data,
cipher=block_cipher)
exe = EXE(pyz,
a.scripts,
[],
exclude_binaries=True,
name='test',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
console=False )
coll = COLLECT(exe,
a.binaries,
a.zipfiles,
a.datas,
strip=False,
upx=True,
upx_exclude=[],
name='test')
my main.py file:
from tkinter import *
from tkinter import ttk
import re
import email_data
import smtplib
import os
__location__ = os.path.realpath(os.path.join(os.getcwd(), os.path.dirname(__file__)))
student_view = None
email_string = ''
def display_email():
def save_and_close():
preview_window.destroy()
preview_window = Toplevel()
preview_window.title("Preview")
preview_window.geometry('-680+300')
preview_window.grab_set()
preview_window.lift(root)
preview_frame = ttk.Frame(preview_window, padding=10)
preview = Text(preview_frame)
close_button = Button(preview_frame, text='Close', command=save_and_close)
preview_frame.grid()
preview.grid(column=0, row=0, sticky='NSEW')
close_button.grid(column=0, row=1, sticky='NSEW')
preview.insert(END, email_string)
def format_email():
global email_string
email_string = email_data.email_string_raw.format(this_lab_name=t1.get(), zoom_date_time=t2.get(),
zoom_link=t3.get(),
zoom_ID=t4.get(),
zoom_passcode=t5.get(), this_lab_supplemental=t6.get(),
this_lab_consisting=t7.get(),
this_lab_due=t8.get(), file_name_tag=t9.get(),
last_lab_reminder=t10.get(),
last_lab_due=t11.get(),
last_lab_supplemental=t12.get(), last_file_name_tag=t13.get())
view_email_button['state'] = 'normal'
send_button['state'] = 'normal'
def send_email():
global p, z, email_string, emails1, emails2
def send_email_final():
smtp_obj = smtplib.SMTP('smtp.office365.com', port=587)
smtp_obj.starttls()
email = email_input.get()
password = email_pass_input.get()
smtp_obj.login(email, password)
from_address = email_input.get()
msg = "Subject: CHML101: Weekly Instructional Email" + '\n\n' + email_string
to_address_list = []
if p.get() == 1:
data = open(os.path.join(__location__, 'students1.txt'))
emails = data.read()
to_address_list = emails.split('\n')
print(to_address_list.__str__())
elif p.get() == 2:
data = open(os.path.join(__location__, 'students2.txt'))
emails = data.read()
to_address_list = emails.split('\n')
print(to_address_list.__str__())
print(msg)
smtp_obj.sendmail(from_address, to_address_list, msg)
def confirm_normal():
confirm_check['state'] = 'normal'
def send_normal():
if z.get() == 1:
send_email_button['state'] = 'normal'
else:
send_email_button['state'] = 'disabled'
send_email_window = Toplevel()
send_email_window.title("Send Email")
send_email_window.geometry('400x175-680+300')
send_email_window.grab_set()
send_email_window.lift(root)
send_frame = ttk.Frame(send_email_window)
email_label = Label(send_frame, text='Enter your email address:')
pass_label = Label(send_frame, text='Enter your email password:')
email_input = Entry(send_frame)
email_pass_input = Entry(send_frame, show='*')
class_label1 = Label(send_frame, text='Email class 1:')
class_label2 = Label(send_frame, text='Email class 2:')
class_radio1 = Radiobutton(send_frame, var=p, value=1, command=confirm_normal)
class_radio2 = Radiobutton(send_frame, var=p, value=2, command=confirm_normal)
confirm_label = Label(send_frame, text='Confirm selection:')
confirm_check = Checkbutton(send_frame, state='disabled', variable=z, command=send_normal)
send_email_button = Button(send_frame, text='Send Email', state='disabled', command=send_email_final)
send_frame.grid(column=0, row=0, sticky='NSEW')
email_label.grid(column=0, row=0, columnspan=2)
pass_label.grid(column=2, row=0, columnspan=2)
email_input.grid(column=0, row=1, columnspan=2)
email_pass_input.grid(column=2, row=1, columnspan=2)
class_label1.grid(column=0, row=2)
class_label2.grid(column=2, row=2)
class_radio1.grid(column=1, row=2)
class_radio2.grid(column=3, row=2)
confirm_label.grid(column=1, row=3)
confirm_check.grid(column=2, row=3)
send_email_button.grid(columnspan=2, column=1, row=4)
def class_list_view():
global emails1, emails2, v, student_view
def update_txt():
items = student_view.get(0, 'end')
if v.get() == 2:
data1 = open(os.path.join(__location__, 'students2.txt'), mode='w')
first = True
for item in items:
if first:
data1.write(item)
first = False
else:
data1.write('\n' + item)
data1.close()
if v.get() == 1:
data1 = open(os.path.join(__location__, 'students1.txt'), mode='w')
first = True
for item in items:
if first:
data1.write(item)
first = False
else:
data1.write('\n' + item)
data1.close()
def check_email():
email = add_student_entry.get()
if re.match(r'\w+@\w+.\w+', email) is not None:
add_student()
add_student_label['text'] = 'Add new student Email:'
update_txt()
else:
add_student_label['text'] = 'EMAIL FORMAT INVALID'
def delete_student():
student_view.delete('active')
update_txt()
def add_student():
if v.get() == 2:
emails2_curr = emails2.get()
emails2_curr = list(emails2_curr)
emails2_curr.append(add_student_entry.get())
emails2.set(emails2_curr)
add_student_entry.delete(0, 'end')
if v.get() == 1:
emails1_curr = emails1.get()
emails1_curr = list(emails1_curr)
emails1_curr.append(add_student_entry.get())
emails1.set(emails1_curr)
add_student_entry.delete(0, 'end')
def assign_class():
if v.get() == 2:
student_view['listvariable'] = emails2
elif v.get() == 1:
student_view['listvariable'] = emails1
class_list = Toplevel()
class_list.title("View/Edit Class Lists")
class_list.geometry('400x200-680+300')
class_list.grab_set()
class_list.lift(root)
student_frame = ttk.Frame(class_list)
student_view = Listbox(student_frame, height=10, width=30)
class1 = Radiobutton(student_frame, text='Class 1', var=v, value=1, command=assign_class)
class2 = Radiobutton(student_frame, text='Class 2', var=v, value=2, command=assign_class)
add_student_label = Label(student_frame, text='Add new student Email:')
add_student_entry = Entry(student_frame, width=30)
add_student_button = Button(student_frame, text='Add', command=check_email)
delete_student_button = Button(student_frame, text='Delete', command=delete_student)
add_student_entry.grid(column=2, row=1, sticky=N)
add_student_label.grid(column=2, row=0, sticky=(N, E, W))
add_student_button.grid(column=2, row=2)
delete_student_button.grid(column=2, row=3)
student_frame.grid(column=0, row=0, sticky=(N, S, E, W))
student_view.grid(column=3, row=0, columnspan=3, rowspan=8, sticky=(N, W, S, E))
class1.grid(column=3, row=8)
class2.grid(column=4, row=8)
root = Tk()
root.title("Dr. Emailio Robotus")
root.geometry('600x700-670+120')
root.minsize(400, 500)
v = IntVar()
p = IntVar()
z = IntVar()
t1 = StringVar()
t2 = StringVar()
t3 = StringVar()
t4 = StringVar()
t5 = StringVar()
t6 = StringVar()
t7 = StringVar()
t8 = StringVar()
t9 = StringVar()
t10 = StringVar()
t11 = StringVar()
t12 = StringVar()
t13 = StringVar()
# data = open('students1.txt', encoding='utf-8')
data = open(os.path.join(__location__, 'students1.txt'))
emails = data.read()
emails1 = emails.split('\n')
emails1 = Variable(value=emails1)
data.close()
data = open(os.path.join(__location__, 'students2.txt'))
emails = data.read()
emails2 = emails.split('\n')
emails2 = Variable(value=emails2)
data.close()
mainframe = ttk.Frame(root, padding="5", borderwidth=5, relief='solid')
this_lab_name = ttk.Entry(mainframe, width=50, background='grey', textvariable=t1)
this_lab_name_label = Label(mainframe, text='This week\'s lab name:')
zoom_date_time = ttk.Entry(mainframe, width=50, background='grey', textvariable=t2)
zoom_date_time_label = Label(mainframe, text='This week\'s Zoom meeting (date/time):')
zoom_link = ttk.Entry(mainframe, width=50, background='grey', textvariable=t3)
zoom_link_label = Label(mainframe, text='This week\'s Zoom link:')
zoom_ID = ttk.Entry(mainframe, width=50, background='grey', textvariable=t4)
zoom_ID_label = Label(mainframe, text='This week\'s Zoom meeting ID:')
zoom_passcode = ttk.Entry(mainframe, width=50, background='grey', textvariable=t5)
zoom_passcode_label = Label(mainframe, text='This week\'s Zoom meeting passcode:')
this_lab_supplemental = ttk.Entry(mainframe, width=50, background='grey', textvariable=t6)
this_lab_supplemental_label = Label(mainframe, text='This week\'s lab\'s supplemental questions:')
this_lab_consisting = ttk.Entry(mainframe, width=50, background='grey', textvariable=t7)
this_lab_consisting_label = Label(mainframe, text='This week\'s lab should be consisting of:')
this_lab_due = ttk.Entry(mainframe, width=50, background='grey', textvariable=t8)
this_lab_due_label = Label(mainframe, text='This week\'s lab is due (date/time):')
file_name_tag = ttk.Entry(mainframe, width=50, background='grey', textvariable=t9)
file_name_tag_label = Label(mainframe, text='This week\'s lab naming format (Aspirin/Hess):')
last_lab_reminder = ttk.Entry(mainframe, width=50, background='grey', textvariable=t10)
last_lab_reminder_label = Label(mainframe, text='Last week\'s lab name:')
last_lab_due = ttk.Entry(mainframe, width=50, background='grey', textvariable=t11)
last_lab_due_label = Label(mainframe, text='Last week\'s lab is due (date/time):')
last_lab_supplemental = ttk.Entry(mainframe, width=50, background='grey', textvariable=t12)
last_lab_supplemental_label = Label(mainframe, text='Last week\'s lab\'s supplemental questions:')
last_file_name_tag = ttk.Entry(mainframe, width=50, background='grey', textvariable=t13)
last_file_name_tag_label = Label(mainframe, text='Last week\'s lab naming format (Aspirin/Hess):')
compile_button = Button(mainframe, text='Compile Email', command=format_email, width=25)
view_email_button = Button(mainframe, text='View Email', state='disabled', command=display_email, width=25)
classes_button = Button(mainframe, text='View/Modify Class List', command=class_list_view, width=18)
send_button = Button(mainframe, text='Send Email...', width=18, state='disabled', command=send_email)
mainframe.grid(column=0, row=0, sticky=(N, S, E, W))
this_lab_name.grid(column=1, row=0, sticky=E, padx=3, pady=3)
this_lab_name_label.grid(column=0, row=0, sticky=W, padx=3, pady=3)
zoom_date_time.grid(column=1, row=1, sticky=E, padx=3, pady=3)
zoom_date_time_label.grid(column=0, row=1, sticky=W, padx=3, pady=3)
zoom_link.grid(column=1, row=2, sticky=E, padx=3, pady=3)
zoom_link_label.grid(column=0, row=2, sticky=W, padx=3, pady=3)
zoom_ID.grid(column=1, row=3, sticky=E, padx=3, pady=3)
zoom_ID_label.grid(column=0, row=3, sticky=W, padx=3, pady=3)
zoom_passcode.grid(column=1, row=4, sticky=E, padx=3, pady=3)
zoom_passcode_label.grid(column=0, row=4, sticky=W, padx=3, pady=3)
this_lab_supplemental.grid(column=1, row=5, sticky=E, padx=3, pady=3)
this_lab_supplemental_label.grid(column=0, row=5, sticky=W, padx=3, pady=3)
this_lab_consisting.grid(column=1, row=6, sticky=E, padx=3, pady=3)
this_lab_consisting_label.grid(column=0, row=6, sticky=W, padx=3, pady=3)
this_lab_due.grid(column=1, row=7, sticky=E, padx=3, pady=3)
this_lab_due_label.grid(column=0, row=7, sticky=W, padx=3, pady=3)
file_name_tag.grid(column=1, row=8, sticky=E, padx=3, pady=3)
file_name_tag_label.grid(column=0, row=8, sticky=W, padx=3, pady=3)
last_lab_reminder.grid(column=1, row=9, sticky=E, padx=3, pady=3)
last_lab_reminder_label.grid(column=0, row=9, sticky=W, padx=3, pady=3)
last_lab_due.grid(column=1, row=10, sticky=E, padx=3, pady=3)
last_lab_due_label.grid(column=0, row=10, sticky=W, padx=3, pady=3)
last_lab_supplemental.grid(column=1, row=11, sticky=E, padx=3, pady=3)
last_lab_supplemental_label.grid(column=0, row=11, sticky=W, padx=3, pady=3)
last_file_name_tag.grid(column=1, row=12, sticky=E, padx=3, pady=3)
last_file_name_tag_label.grid(column=0, row=12, sticky=W, padx=3, pady=3)
compile_button.grid(column=0, row=13, columnspan=2, padx=3, pady=3)
view_email_button.grid(column=0, row=14, columnspan=2, padx=3, pady=3)
classes_button.grid(row=15, column=0, columnspan=2, padx=3, pady=3)
send_button.grid(row=16, column=0, columnspan=2, padx=3, pady=3)
root.columnconfigure(0, weight=1)
root.rowconfigure(0, weight=1)
# mainframe.rowconfigure(0, weight=1)
# mainframe.columnconfigure(0, weight=1)
# mainframe.rowconfigure(0, weight=1)
# mainframe.columnconfigure(0, weight=1)
if __name__ == '__main__':
root.mainloop()
Upvotes: 2
Views: 3403
Reputation: 21
Following the advice given I was able to get the program to run. I had to change the .spec file, specifically the datas field in order to get it to work.
However I was then having a problem where the .txt files would load into the program, but upon editing them the edits were not saved as they should be. Solution: I had not put the files into 'w' mode, and this is why I wasn't getting any output to the text files. All is working now! Thank you to everyone for helping. I have updated the files above to reflect the final working version
Upvotes: 0
Reputation: 1123
Try the below spec
file. I just changed the property console=True
to console=False
Note that now you need to run pyinstaller main.spec
instead of pyinstaller main.py
.
If you don't want to use this spec file, and just want to do it from the script add --noconsole
or --windowed
in command when you run pyinstaller main.py
.
eg pyinstaller main.py --noconsole
.
# -*- mode: python ; coding: utf-8 -*-
block_cipher = None
a = Analysis(['__main__.py'],
pathex=['C:\\Users\\wiley\\PycharmProjects\\EmailBot\\email_bot'],
binaries=[],
datas=[],
hiddenimports=[],
hookspath=[],
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False)
pyz = PYZ(a.pure, a.zipped_data,
cipher=block_cipher)
exe = EXE(pyz,
a.scripts,
[],
exclude_binaries=True,
name='__main__',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
console=False)
coll = COLLECT(exe,
a.binaries,
a.zipfiles,
a.datas,
strip=False,
upx=True,
upx_exclude=[],
name='__main__')
Upvotes: 1