First I have to say that I just started Python programming. I do automatic inventory balance checking, mainly as a hobby.
I need help with my program...
This opens the excel file and looks for the value 0, in the B column.
if there is a 0 in the column which means that the part has run out, the code will send an e-mail with the title of the article from column A
When I did the debugging I noticed if i update the the Excel file that code uses in Exel at the same time the program happens to read the table, i get "Excel sharing violation error"
this is not a big problem because the final program will read the file once or twice a day but there is a small chance of an error, probably something else will crash, hopefully not.
I tried all these common ways with Exel
-Authorize Indexing for file Folders
-Permitting Sharing Wizard
-Saved file to a different location
-Renamed file
-i don't use third party Antivirus program
So would you have any tips on how i can improve the code, get rid of the above error and continue learning.
import threading
import tkinter as tk
from tkinter import BOTTOM,Label, Menu
import os
import smtplib
import datetime
import time
from time import sleep
import pandas as pds
root = tk.Tk()
root.title('Timer')
sec = 0
def timer():
global sec
sec += 1
time['text'] = sec
time.after(1000, timer)
time = Label(root, fg='black')
time.pack()
contact_num = os.environ.get("Contact_number")
contact_email = os.environ.get("Contact_email")
L = Label(root, text="Automatic warehouse alarm").pack()
L_2 = Label(root, text="START, Run program").pack()
root.title("Warehouse 1.4.2")
root.geometry("460x360")
class get_data:
def get_empty_stock(self):
while(True):
Email_adress = os.environ.get("email_user")
Email_password = os.environ.get("email.password")
file = ("C:\Exel_files\SpareParts_Vers25.xlsx")
try:
dataFrame = pds.read_excel(file)
except PermissionError:
print("PermissionError")
else:
pass
booleans = []
for Amount in dataFrame.Amount:
if Amount <= 0:
booleans.append(True)
else:
booleans.append(False)
if True in booleans:
empty_stock = dataFrame.loc[dataFrame.Amount <= 0]
with smtplib.SMTP("smtp.gmail.com",587) as smtp_server:
time_date = datetime.datetime.now()
time = time_date.strftime("%H:%M:%S")
date = time_date.strftime("%d/%m/%Y")
smtp_server.ehlo()
smtp_server.starttls()
smtp_server.ehlo()
smtp_server.login(Email_adress,Email_password)
subject = "Warehouse"
body = f"""{empty_stock}\nPart is out of stock
{date}\n
{time}\n
"""
msg = f"subject: {subject}\n\n{body}"
smtp_server.sendmail(Email_adress,Email_adress, msg)
sleep(25)
def __init__(self):
t = threading.Thread(target=self.get_empty_stock)
t.start()
Start = tk.Button(root, text = "START", width= 25, command=lambda:[get_data(),timer()]).pack()
Stop = tk.Button(root, text = "QUIT", width= 25, command= root.quit).pack(side=BOTTOM)
menu = Menu(root)
root.config(menu=menu)
helpmenu = Menu(menu)
menu.add_cascade(label='menu', menu=helpmenu)
helpmenu.add_command(label=contact_email)
helpmenu.add_command(label=contact_num)
helpmenu.add_command(label= "Exit", command=root.quit)
root.mainloop()
To avoid multi-user sharing violation, consider copying the last saved instance of Excel file using a tempfile and point read_excel to this temp file which is automatically deleted after the with context:
import shutil
import tempfile
...
file = "C:\Exel_files\SpareParts_Vers25.xlsx"
with tempfile.NamedTemporaryFile() as tmp:
# COPY EXCEL FILE TO TEMP FILE
shutil.copyfile(file, tmp.name)
try:
# READ IN TEMP FILE
dataFrame = pds.read_excel(tmp.name)
except PermissionError:
print("PermissionError")
Related
I have designed an marine engine simulator - it's a program that sends some serial DATA using a certain protocol called "BlueVision". The data is encoded based on a header, a block number, a block type, actual data (indexed), a checksum and a footer. Due to the fact that if you want to change a value in the actual data - then the checksum changes - I designed an recalculation of the block with the correct checksum when the data is changed. I made a GUI that allows me to change the value of 2 data points in order to be able to test live. The problem is that I don't know how to use threads or subprocesses correctly and the window keeps on freezing. The application works - but works badly and I kept on searching for a similar issue - and did find some suggestions but I haven't been able to implement it. Can someone help? PS: the code is awkward at best - please don't judge - I know I could of made it way better - but this is the best I could do with the time I had. The issue might not be clear to you if you don't have a COM port where the program writes to.
# Blue Vision is a MTU serial communication protocol - based on HEX values grouped in BLOCKS
import tkinter as tk
from tkinter import ttk
import time
import serial
def split_by_n(seq, n):
while seq:
yield seq[:n]
seq= seq[n:]
def after(self, ms, func=None, *args):
"""Call function once after given time.
MS specifies the time in milliseconds. FUNC gives the
function which shall be called. Additional parameters
are given as parameters to the function call. Return
identifier to cancel scheduling with after_cancel."""
win = tk.Tk()
win.title("GUI - TEST VERSION")
win.geometry("750x250")
label = tk.Label(win, text = "Main Engine Overspeed")
label.pack()
v = tk.StringVar()
v.set('00')
c = tk.StringVar()
c.set("00")
def setText(word):
v.set(word)
a = ttk.Button(win, text ="01", command =lambda:setText("01"))
a.pack()
b = ttk.Button(win, text="00", command = lambda:setText("00"))
b.pack()
label1 = tk.Label(win, text ="Main Engine Speed")
label1.pack()
name_entry = tk.Entry(win, textvariable=c)
name_entry.pack()
def task():
MyVar = v.get()
priEngSp =c.get()
if len(priEngSp) == 0:
priEngSp = '00'
block_3 = 'FAF500030002000000290100000001000100000001000001000000000000000000000000000222AF5F'
block_4 = 'FAF500040003000001A000004650000047E00000000000000000000000000007EF4000083D6000000000000000000000000000000000000000000000012C000006D600000000000000000000278D00000000000000007FFFFFFF000000000001991500000000000000000016E36000000000000923D8000971F8000001F40000059F000026AC00002774000005800000251C00000580000027740000283C0000056200001D4C00001F400000061800000000000060FB00004650000036B000007D0000008CA0000006180000251C0000000000000000000000000000284800192D500017A6B00000051B0000251CFFFFFFA8000002580000044C000000FA0000000000000000000006770000CB200000D6D8000006770000CB200000D6D80000060600005DC000000000000027100000000000000000000000000000000000000000000003C2000061A8000000000000000000000000000000000000000000000000000000000000000000000000000000000000363300000EA6000249F0FFFFFB1E000F42400000000000000000000000000000000000000000000032D9AF5F'
block_5 = 'FAF5000500020000005600000000000000000000000000000000000000000000007F7F0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034AAF5F'
block_6 = 'FAF5000600020000003D00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000234AF5F'
block_7 = 'FAF5000700030000008C000006280000064A0000064A0000068D0000066B0000068D0000068D000006AE0000000000000000000006AE000006070000060700000607000005E5000005A2000006070000064A00000000000000000000062A000006AE000005A20000350EFFFFF07C00003CDEFFFFE8AC00000000000000000000000000000000000012DEAF5F'
block_8 = 'FAF50008000300000070000000000000112900000000000000000000059C000027740000283C000047E000000000000000000000000000000000000000000000000000000000000000007FFFFFFF7FFFFFFF0000055100002CEC0000000000000000000000000000000000000DD1AF5F'
block_9 = 'FAF50009000200000020000000000000000000000000000000000000021AAF5F'
block_10 = 'FAF5000A0002000000260000000000000000000000000000000000000000000000000221AF5F'
block_11 = 'FAF5000B0003000000EC00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002E9AF5F'
block_12 = 'FAF5000C000200000045000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000242AF5F'
block_2 = 'FAF50002000200000074010001000000000000000000000000000000000000000000007F0000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002E9AF5F'
checksum = hex(0x00)
block_2split = list(split_by_n(block_2,2))
block_2split[10] = MyVar.upper() #Overspeed Alarm Position
for i in range(len(block_2split)-6):
checksum = hex(int(checksum, 16) + int(block_2split[i], 16))
checksum_string = str(checksum)
checksum_actvalue = checksum_string[2:]
checksum_long = checksum_actvalue.rjust(8,'0').upper()
checksum_split = list(split_by_n(checksum_long,2))
block_2split[len(block_2split)-3] = checksum_split[3]
block_2split[len(block_2split)-4] = checksum_split[2]
block_2split[len(block_2split)-5] = checksum_split[1]
block_2split[len(block_2split)-6] = checksum_split[0]
Block_2Output = ''.join(str(item) for item in block_2split)
iEngineSpeed = int(priEngSp,10)
hEngineSpeed = hex(iEngineSpeed * 10)
sEngineSpeed = str(hEngineSpeed)[2:].upper()
while (len(sEngineSpeed)<8):
sEngineSpeed = '0' + sEngineSpeed
block_4split = list(split_by_n(block_4,4))
sEngineSpeed_split = list(split_by_n(sEngineSpeed,4))
block_4split[5] = sEngineSpeed_split[0]
block_4split[6] = sEngineSpeed_split[1]
Block_4joint = ''.join(str(item) for item in block_4split)
Block_4joint_sp = list(split_by_n(Block_4joint,2))
checksumb4 = hex(0x00)
for i in range(len(Block_4joint_sp)-6):
checksumb4 = hex(int(checksumb4, 16) + int(Block_4joint_sp[i], 16))
checksumb4_string = str(checksumb4)
checksumb4_actvalue = checksumb4_string[2:]
checksumb4_long = checksumb4_actvalue.rjust(8,'0').upper()
checksumb4_split = list(split_by_n(checksumb4_long,2))
Block_4joint_sp[len(Block_4joint_sp)-3] = checksumb4_split[3]
Block_4joint_sp[len(Block_4joint_sp)-4] = checksumb4_split[2]
Block_4joint_sp[len(Block_4joint_sp)-5] = checksumb4_split[1]
Block_4joint_sp[len(Block_4joint_sp)-6] = checksumb4_split[0]
Block_4Output = ''.join(str(item) for item in Block_4joint_sp)
blocks = [Block_2Output, block_3, Block_4Output, block_5, block_6, block_7, block_8, block_9, block_10, block_11, block_12]
with serial.Serial('COM5', '9600') as ser: #you might wanna comment this part out
for block in blocks:
print(block)
ser.write(bytes.fromhex(block.strip())) #you might wanna comment this part out
time.sleep(1)
win.after(200, task)
win.after(200, task)
win.mainloop()
To avoid freezing, one of the way is to use thread:
from threading import Thread
...
def task():
while True:
MyVar = v.get()
...
blocks = [Block_2Output, block_3, Block_4Output, block_5, block_6, block_7, block_8, block_9, block_10, block_11, block_12]
with serial.Serial('COM5', '9600') as ser: #you might wanna comment this part out
for block in blocks:
print(block)
ser.write(bytes.fromhex(block.strip())) #you might wanna comment this part out
time.sleep(1)
time.sleep(0.2)
# run task() in a thread
Thread(target=task, daemon=1).start()
win.mainloop()
I am creating a piece of software for my organisation which I recently started, and I am using the Tkinter module in Python to create my software. The software is similar to how an operating system works, but it isn't an operating system, and it runs like a normal program on your desktop. In the software, there are numerous applications, like a word-processor (more on that later), a spreadsheet editor, etc.
The first application I am creating is a word processor called Wordee, and I've based it on a style that mirrors Microsoft Notepad. I want the user to click a button and the word-processor opens code from a class in another file in the same directory. This class is the code for the word processor.
I have written that code, but it always opens the word processor first and then when you close the word processor, the window that you should access the word processor from.
Here is the code which I am currently developing - everything that I have written was where I got up to when I noticed the problem:
from tkinter import *
import time
import os
import wordProcessorExample as wPE
window = Tk()
window.title("Brainwave One")
def get_datetime():
timeVariable = time.strftime("%I:%M %p, %A %d %B %Y")
date_time.config(text=timeVariable)
date_time.after(200,get_datetime)
def wordee():
print(wPE.Wordee)
date_time = Label(window,font=("Calibri",15))
date_time.grid(row=0,column=0)
title = Label(window,text="Brainwave One",font=("Calibri",40))
title.place(relx=0.5,rely=0.05,anchor="center")
title = Label(window,text="From The Brainwave Incorporation",font=("Calibri",13))
title.place(relx=0.5,rely=0.083,anchor="center")
wordee = Button(window,text="Wordee",font=("Calibri",23),command=wordee)
wordee.place(relx=0.25,rely=0.1875,anchor="center")
get_datetime()
window.mainloop()
Here is the other file that I am accessing the class for the word processor from:
import tkinter
import os
from tkinter import *
from tkinter.messagebox import *
from tkinter.filedialog import *
class Wordee:
__root = Tk()
# default window width and height
__thisWidth = 300
__thisHeight = 300
__thisTextArea = Text(__root)
__thisMenuBar = Menu(__root)
__thisFileMenu = Menu(__thisMenuBar, tearoff=0)
__thisEditMenu = Menu(__thisMenuBar, tearoff=0)
__thisHelpMenu = Menu(__thisMenuBar, tearoff=0)
# To add scrollbar
__thisScrollBar = Scrollbar(__thisTextArea)
__file = None
def __init__(self,**kwargs):
# Set icon
try:
self.__root.wm_iconbitmap("Wordee.ico")
except:
pass
# Set window size (the default is 300x300)
try:
self.__thisWidth = kwargs['width']
except KeyError:
pass
try:
self.__thisHeight = kwargs['height']
except KeyError:
pass
# Set the window text
self.__root.title("Untitled - Wordee")
# Center the window
screenWidth = self.__root.winfo_screenwidth()
screenHeight = self.__root.winfo_screenheight()
# For left-align
left = (screenWidth / 2) - (self.__thisWidth / 2)
# For right-align
top = (screenHeight / 2) - (self.__thisHeight /2)
# For top and bottom
self.__root.geometry('%dx%d+%d+%d' % (self.__thisWidth,
self.__thisHeight,
left, top))
# To make the textarea auto resizable
self.__root.grid_rowconfigure(0, weight=1)
self.__root.grid_columnconfigure(0, weight=1)
# Add controls (widget)
self.__thisTextArea.grid(sticky = N + E + S + W)
# To open new file
self.__thisFileMenu.add_command(label="New",
command=self.__newFile)
# To open a already existing file
self.__thisFileMenu.add_command(label="Open",
command=self.__openFile)
# To save current file
self.__thisFileMenu.add_command(label="Save",
command=self.__saveFile)
# To create a line in the dialog
self.__thisFileMenu.add_separator()
self.__thisFileMenu.add_command(label="Exit",
command=self.__quitApplication)
self.__thisMenuBar.add_cascade(label="File",
menu=self.__thisFileMenu)
# To give a feature of cut
self.__thisEditMenu.add_command(label="Cut",
command=self.__cut)
# to give a feature of copy
self.__thisEditMenu.add_command(label="Copy",
command=self.__copy)
# To give a feature of paste
self.__thisEditMenu.add_command(label="Paste",
command=self.__paste)
# To give a feature of editing
self.__thisMenuBar.add_cascade(label="Edit",
menu=self.__thisEditMenu)
# To create a feature of description of the notepad
self.__thisHelpMenu.add_command(label="About Wordee",
command=self.__showAbout)
self.__thisMenuBar.add_cascade(label="Help",
menu=self.__thisHelpMenu)
self.__root.config(menu=self.__thisMenuBar)
self.__thisScrollBar.pack(side=RIGHT,fill=Y)
# Scrollbar will adjust automatically according to the content
self.__thisScrollBar.config(command=self.__thisTextArea.yview)
self.__thisTextArea.config(yscrollcommand=self.__thisScrollBar.set)
def __quitApplication(self):
self.__root.destroy()
# exit()
def __showAbout(self):
showinfo("Notepad","Mrinal Verma")
def __openFile(self):
self.__file = askopenfilename(defaultextension=".wde",
filetypes=[("All Files","*.*"),
("Text Documents","*.wde")])
if self.__file == "":
# no file to open
self.__file = None
else:
# Try to open the file
# set the window title
self.__root.title(os.path.basename(self.__file) + " - Wordee")
self.__thisTextArea.delete(1.0,END)
file = open(self.__file,"r")
self.__thisTextArea.insert(1.0,file.read())
file.close()
def __newFile(self):
self.__root.title("Untitled - Wordee")
self.__file = None
self.__thisTextArea.delete(1.0,END)
def __saveFile(self):
if self.__file == None:
# Save as new file
self.__file = asksaveasfilename(initialfile='Untitled.wde',
defaultextension=".wde",
filetypes=[("All Files","*.*"),
("Text Documents","*.wde")])
if self.__file == "":
self.__file = None
else:
# Try to save the file
file = open(self.__file,"w")
file.write(self.__thisTextArea.get(1.0,END))
file.close()
# Change the window title
self.__root.title(os.path.basename(self.__file) + " - Wordee")
else:
file = open(self.__file,"w")
file.write(self.__thisTextArea.get(1.0,END))
file.close()
def __cut(self):
self.__thisTextArea.event_generate("<<Cut>>")
def __copy(self):
self.__thisTextArea.event_generate("<<Copy>>")
def __paste(self):
self.__thisTextArea.event_generate("<<Paste>>")
def run(self):
# Run main application
self.__root.mainloop()
# Run main application
Wordee = Wordee(width=600,height=400)
Wordee.run()
I created a python script (NoShowCalc.py) that automates data cleaning and analysis with 3 selected excel files (booked_file_path, arrived_file_path, and vlookup_file_path). However, I want this all to be executed through a GUI, so I started a separate (GUI.py) script to create an interface with browse buttons that will get those file path names, then that will get me what I need to execute the NoShowCalc.py script. Once those excel files are selected, another button is there to execute the NoShowCalc.py script. However, I did it and it worked! But I have no idea what I changed and now the two different py files are not connecting.
Here's the script in the NoShowGUI.py script:
def open_file():
browse_text.set('Loading...')
booked_file_path = askopenfile(parent=root, mode='rb', title='Choose a file', filetype=[('CSV file', '*.csv')])
if booked_file_path:
read_csv = (booked_file_path)
browse_text.set('Loaded')
def run():
os.system('NoShow_Calc.py')
calculate_text.set("Calculating...")
#Calculate button
calculate_text = tk.StringVar()
calculate_btn = tk.Button(root, textvariable=calculate_text, command=lambda:run(), font='Calibri', fg='black', height=1, width=15)
calculate_text.set("Calculate No Show")
calculate_btn.grid(column=2, row=9)
These are the first lines in the NoShowCalc.py script:
import pandas as pd
booked = pd.read_csv(booked_file_path, parse_dates=['Appointment Date'])
arrived = pd.read_csv(arrived_file_path, parse_dates=['Appointment Date'])
vlookup = pd.read_excel(vlookup_file_path)
The error that keeps popping up is NameError: name 'booked_file_path' is not defined. I don't get how it ran before and now this error is popping up as it can't speak to the other py file anymore. What did I do wrong?
If you run script using os.system() or using module subprocess then you can't use variables from other script. They runs as separated processes and they can't share variable (or data in memory)
You can only send some text values as arguments
os.system('NoShow_Calc.py ' + booked_file_path)
and then you can get it inside NoShow_Calc using sys.argv
import pandas as pd
import sys
booked_file_path = sys.argv[1]
booked = pd.read_csv(booked_file_path, parse_dates=['Appointment Date'])
arrived = pd.read_csv(arrived_file_path, parse_dates=['Appointment Date'])
vlookup = pd.read_excel(vlookup_file_path)
If you need other variables then you have to send other values in the same way
os.system('NoShow_Calc.py ' + booked_file_path + ' ' + other_filename)
and
booked_file_path = sys.argv[1]
other_filename = sys.argv[2]
# etc.
But using os.system() you can't send result booked, arrived, vlookup from NoShow_Calc to NoShowGUI.
You could do it with subprocess but it can send it only as text - so NoShow_Calc would have to use print() to display all result and NoShowGUI would have to parse this text to expected structure - ie. list, dictionary, DataFrame
Better you should use import to load code from NoShow_Calc.py and then all code runs in the same process so all code has access to the same variables - and it doesn't need to convert to text and back from text.
To make it better I put code in function
import pandas as pd
def my_function(booked_file_path, arrived_file_path, vlookup_file_path):
booked = pd.read_csv(booked_file_path, parse_dates=['Appointment Date'])
arrived = pd.read_csv(arrived_file_path, parse_dates=['Appointment Date'])
vlookup = pd.read_excel(vlookup_file_path)
return booked, arrived, vlookup
and then in NoShowGUI you can import it and use like any other function
from NoShow_Calc import my_function
booked, arrived, vlookup = my_function(booked_file_path, arrived_file_path, vlookup_file_path)
EDIT:
I made minimal working code. I reduced it to only one filename.
NoShow_Calc.py
import pandas as pd
def calc(booked_file_path): #, arrived_file_path, vlookup_file_path):
booked = pd.read_csv(booked_file_path, parse_dates=['Appointment Date'])
#arrived = pd.read_csv(arrived_file_path, parse_dates=['Appointment Date'])
#vlookup = pd.read_excel(vlookup_file_path)
return booked #, arrived, vlookup
NoShowGUI.py
import tkinter as tk
from tkinter.filedialog import askopenfilename # instead of `askopenfile`
# adding directory with this script to `sys.path` before `import NoShow_Calc`
# to make sure that `import` will search `NoShow_Calc.py` in correct folder even when GUI will be run from different folder
import os
import sys
HOME_DIR = os.path.dirname(os.path.abspath(__file__))
sys.path.append(HOME_DIR)
import NoShow_Calc
print('HOME_DIR:', HOME_DIR)
def select_filename():
global booked_file_path # inform function that it has to assign value to external/global variable
text_log.insert('end', 'Selecting ...\n')
# use `askopenfilename` instead of `askopenfile`
# because I need only filename, not opened file (pandas will open it on its own)
booked_file_path = askopenfilename(parent=root,
title='Choose a file',
#initialdir='/home/furas',
filetypes=[('CSV file', '*.csv')])
if booked_file_path:
text_log.insert('end', f'Selected: {booked_file_path}\n')
else:
text_log.insert('end', f'Not selected\n')
def run():
text_log.insert('end', "Calculating...\n")
if booked_file_path is None:
text_log.insert('end', "File booked_file_path not selected !!!")
return
#elif arrived_file_path is None:
# text_log.insert('end', "File arrived_file_path not selected !!!")
# return
#elif vlookup_file_path is None:
# text_log.insert('end', "File vlookup_file_path not selected !!!")
# return
else:
root.update() # force tkinter to update text in text_log at once (not when it exits function `run`)
result = NoShow_Calc.calc(booked_file_path)# , arrived_file_path, vlookup_file_path)
text_log.insert('end', "Result:\n")
text_log.insert('end', str(result.head()) + "\n")
# --- main ---
booked_file_path = None # default value at start (so in `run` I can check `None` to see if I selecte filename)
#arrived_file_path = None
#vlookup_file_path = None
root = tk.Tk()
text_log = tk.Text(root)
text_log.grid(column=0, row=0)
select_btn = tk.Button(root, text="Select File Name", command=select_filename)
select_btn.grid(column=0, row=1)
calculate_btn = tk.Button(root, text="Calculate", command=run)
calculate_btn.grid(column=0, row=2)
root.mainloop()
I have written a program in Python that allow me to change the names of many files all at once. I have one issue that is quite odd.
When I use raw_input to get my desired extension, the GUI will not launch. I don't get any errors, but the window will never appear.
I tried using raw_input as a way of getting a file extension from the user to build the file list. This program will works correctly when raw_input is not used.The section of code that I am referring to is in my globList function. For some reason when raw_imput is used the window will not launch.
import os
import Tkinter
import glob
from Tkinter import *
def changeNames(dynamic_entry_list, filelist):
for index in range(len(dynamic_entry_list)):
if(dynamic_entry_list[index].get() != filelist[index]):
os.rename(filelist[index], dynamic_entry_list[index].get())
print "The files have been updated!"
def drawWindow(filelist):
dynamic_entry_list = []
my_row = 0
my_column = 0
for name in filelist:
my_column = 0
label = Tkinter.Label(window, text = name, justify = RIGHT)
label.grid(row = my_row, column = my_column)
my_column = 1
entry = Entry(window, width = 50)
dynamic_entry_list.append(entry)
entry.insert(0, name)
entry.grid(row = my_row, column = my_column)
my_row += 1
return dynamic_entry_list
def globList(filelist):
#ext = raw_input("Enter the file extension:")
ext = ""
desired = '*' + ext
for name in glob.glob(desired):
filelist.append(name)
filelist = []
globList(filelist)
window = Tkinter.Tk()
user_input = drawWindow(filelist)
button = Button(window, text = "Change File Names", command = (lambda e=user_input: changeNames(e, filelist)))
button.grid(row = len(filelist) + 1 , column = 1)
window.mainloop()
Is this a problem with raw_input?
What would be a good solution to the problem?
This is how tkinter is defined to work. It is single threaded, so while it's waiting for user input it's truly waiting. mainloop must be running so that the GUI can respond to events, including internal events such as requests to draw the window on the screen.
Generally speaking, you shouldn't be mixing a GUI with reading input from stdin. If you're creating a GUI, get the input from the user via an entry widget. Or, get the user input before creating the GUI.
A decent tutorial on popup dialogs can be found on the effbot site: http://effbot.org/tkinterbook/tkinter-dialog-windows.htm
I'm creating a tkinter gui that will take user input for a variable that then gets passed to SQL and the queried data (in this case a single column data frame and boxplot). However, at this moment I can not find a means of displaying my pandas dataframe in the tk gui. I have not found any module or means of displaying this, and I've spent hours going through possible solutions to no avail. Only thing I need is for the dataframe to display in the gui and be re-rendered each time I change the dataframe through the user input function. My code atm is:
### Starting first GUI/Tkinter Script
##First load libs
import pyodbc
import numpy as np
import pandas.io.sql as sql
import pandas
import matplotlib.pyplot as plt
import pylab
import matplotlib as mpl
from tkinter import *
import sys
plt.ion()
def userinput():
global PartN, pp, df
##a = raw_input(v.get())
a = E1.get()
##print a
PartN = a
conn = pyodbc.connect('DRIVER={SQL Server};SERVER=my server;
DATABASE=PackingList;UID=myid;PWD=mypword')
sqlr = "SELECT partmadeperhour FROM Completions WHERE PartNumber = ?
AND endtime > '2012-12-31 23:59:00' ORDER BY partmadeperhour"
df = pandas.read_sql_query(sqlr, conn, params=[PartN])
conn.close()
print(df)
stats = df['partmadeperhour'].describe()
print(stats)
print("Part Name is %s" %PartN)
##df.plot(kind='box', fontsize='20')
pp = df.plot(kind='box', fontsize='20')
plt.show(block=True)
def clear_textbox():
E1.delete(0, END)
master = Tk()
master.title('Title')
v = StringVar()
PartN = None
L1 = Label(master, text = 'Name')
L1.pack(side = LEFT)
E1 = Entry(master, textvariable = v, bd = 5)
E1.pack(side = RIGHT)
b = Button(master, text = 'Submit', command = userinput)
b.pack(side = TOP)
b2 = Button(master, text = 'Clear', command=clear_textbox)
b2.pack(side=BOTTOM)
master.mainloop()
An example of my data frame
rate
0 [0.25]
1 [0.67]
2 [0.93]
... ...
1474 [5400.00]
If someone could just point me in the right direction, I don't even need code corrections just yet, I just need to hear someone to say yes it is possible (which I know it is), and to give me some kind of example. Thanks
I don't have enough rep to comment, otherwise I would, but I used this video to get a grasp of interacting with pandas/numpy/matplotlib and tkinter. He ends up building a large application with it if you stick through all the videos.
Even though you aren't likely doing the exact same thing, I think there might still be useful methods of interacting with your data and GUI gleamed from the videos.
If the link ever dies, you can search on YouTube "Tkinter tutorial sentdex"
Best of luck.