Attached below is a Tkinter script that demonstrates polling, that is,
performing a long-running process in parallel with the GUI. The
script asks for an input file name and an output file name and copies
the input file to the output file. The copy operation is done in a
child process managed with pexpect, and the GUI reports the progress
of the file copy using a Scale widget as a progress bar.
Cordially,
John W. Shipman, NM Tech Computer Center, Socorro, NM; j...@nmt.edu
#!/usr/bin/env python
#
# copyprogress: File copy with a progress bar for Tkinter 8.4.
# - Demonstrates Tkinter .after() and the pexpect module.
# Written by John W. Shipman (j...@nmt.edu), New Mexico Tech
# Computer Center, Socorro, NM 87801 USA. This script is in
# the public domain.
#
# - - - - - I m p o r t s
import sys, os, stat
import Tkinter as tk
import tkFileDialog, tkMessageBox
import pexpect
# - - - - - M a n i f e s t c o n s t a n t s
BUTTON_FONT = ("Helvetica", 17)
LABEL_FONT = ("Helvetica", 14)
ENTRY_FONT = ("DejaVu Sans Mono", 12)
POLL_TIME = 50 # Polling frequency in milliseconds
# - - - - - m a i n
def main():
"""
"""
app = App()
app.master.title("Copy with progress bar")
app.mainloop()
# - - - - - c l a s s A p p
class App(tk.Frame):
'''Copies a file with a progress bar.
Widgets:
.fromFileVar:StringVar for source file name
.fromFileEntry: Entry for source file name
.fromFileBrowse: Browse button for source file name
.fromFileLabel: Label for above
.toFileVar: StringVar for destination file name
.toFileEntry:Entry for destination file name
.toFileBrowse: Browse button for destination file name
.toFileLabel:Label for above
.copyButton: Button to start copying
.progressVar:DoubleVar for progress scale
.progressScale: Scale to show progress
Grid plan:
01 2
++-++
0 | .fromFileEntry | .fromFileBrowse | .fromFileLabel |
++-++
1 | .toFileEntry | .toFileBrowse | .toFileLabel |
++-++
2 | .progress | .copyButton | .quitButton|
++-++
Internal state:
.fromFileSize: Source file size in bytes
.child: pexpect child process to do the copy
'''
# - - - A p p . _ _ i n i t _ _
def __init__(self, master=None):
tk.Frame.__init__(self, master)
self.grid()
self.__createWidgets()
# - - - A p p . _ _ c r e a t e w i d g e t s
def __createWidgets(self):
'''Create all widgets and associated variables.
'''
self.fromFileVar = tk.StringVar()
self.fromFileEntry = tk.Entry ( self,
textvariable=self.fromFileVar,
font=ENTRY_FONT, width=50 )
rowx, colx = 0, 0
self.fromFileEntry.grid(row=rowx, column=colx, sticky=tk.E)
self.fromFileBrowse = tk.Button ( self,
command=self.__browseFrom,
font=BUTTON_FONT, text="Browse" )
colx += 1
self.fromFileBrowse.grid(row=rowx, column=colx)
self.fromFileLabel = tk.Label ( self,
font=LABEL_FONT, text="Source file" )
colx += 1
self.fromFileLabel.grid(row=rowx, column=colx, sticky=tk.W)
self.toFileVar = tk.StringVar()
self.toFileEntry = tk.Entry ( self,
textvariable=self.toFileVar,
font=ENTRY_FONT, width=50 )
rowx, colx = rowx+1, 0
self.toFileEntry.grid(row=rowx, column=colx, sticky=tk.E)
self.toFileBrowse = tk.Button ( self,
command=self.__browseTo,
font=BUTTON_FONT, text="Browse" )
colx += 1
self.toFileBrowse.grid(row=rowx, column=colx)
self.toFileLabel = tk.Label ( self,
font=LABEL_FONT, text="Destination file")
colx += 1
self.toFileLabel.grid(row=rowx, column=colx, sticky=tk.W)
self.progressVar = tk.DoubleVar()
self.progressScale = tk.Scale ( self,
length=400, orient=tk.HORIZONTAL,
from_=0.0, to=100.0, resolution=0.1, tickinterval=20.0,
variable=self.progressVar,
label="Percent completion", font=LABEL_FONT )
rowx, colx = rowx+1, 0
self.progressScale.grid(row=rowx, column=colx, sticky=tk.E)
self.copyButton = tk.Button ( self,
command=self.__copyHandler,
font=BUTTON_FONT, text="Copy" )
colx += 1
self.copyButton.grid(row=rowx, column=colx )
self.quitButton = tk.Button ( self, command=self.qu