171171import zipfile
172172from hashlib import md5
173173from xml .etree import ElementTree
174-
175- try :
176- TKINTER = True
177- from tkinter import Button , Canvas , Entry , Frame , IntVar , Label , Menu , TclError , Tk
178- from tkinter .messagebox import showerror
179-
180- from nltk .draw .table import Table
181- from nltk .draw .util import ShowText
182- except ImportError :
183- TKINTER = False
184- TclError = ValueError
185-
186174from urllib .error import HTTPError , URLError
187175from urllib .request import urlopen
188176
@@ -1103,17 +1091,27 @@ def _set_download_dir(self, download_dir):
11031091 # /////////////////////////////////////////////////////////////////
11041092
11051093 def _interactive_download (self ):
1094+ # Only import tkinter if the user has indicated that they
1095+ # want to draw a UI. See issue #2949 for more info.
1096+ if os .environ .get ('NLTK_DOWNLOADER_FORCE_INTERACTIVE_SHELL' , 'false' ).lower () == 'true' :
1097+ DownloaderShell (self ).run ()
1098+ return
1099+
11061100 # Try the GUI first; if that doesn't work, try the simple
11071101 # interactive shell.
1108- if TKINTER :
1109- try :
1110- DownloaderGUI (self ).mainloop ()
1111- except TclError :
1112- DownloaderShell (self ).run ()
1113- else :
1102+ try :
1103+ import tkinter
1104+ except ImportError :
1105+ DownloaderShell (self ).run ()
1106+ return
1107+
1108+ try :
1109+ DownloaderGUI (self ).mainloop ()
1110+ except tkinter .TclError :
11141111 DownloaderShell (self ).run ()
11151112
11161113
1114+
11171115class DownloaderShell :
11181116 def __init__ (self , dataserver ):
11191117 self ._ds = dataserver
@@ -1370,6 +1368,10 @@ class DownloaderGUI:
13701368 # /////////////////////////////////////////////////////////////////
13711369
13721370 def __init__ (self , dataserver , use_threads = True ):
1371+ # Only import tkinter if the user has indicated that they
1372+ # want to draw a UI. See issue #2949 for more info.
1373+ import tkinter
1374+ from tkinter .messagebox import showerror
13731375 self ._ds = dataserver
13741376 self ._use_threads = use_threads
13751377
@@ -1388,7 +1390,7 @@ def __init__(self, dataserver, use_threads=True):
13881390 self ._log ("NLTK Downloader Started!" )
13891391
13901392 # Create the main window.
1391- top = self .top = Tk ()
1393+ top = self .top = tkinter . Tk ()
13921394 top .geometry ("+50+50" )
13931395 top .title ("NLTK Downloader" )
13941396 top .configure (background = self ._BACKDROP_COLOR [1 ])
@@ -1428,23 +1430,28 @@ def _log(self, msg):
14281430 # /////////////////////////////////////////////////////////////////
14291431
14301432 def _init_widgets (self ):
1433+ # Only import tkinter if the user has indicated that they
1434+ # want to draw a UI. See issue #2949 for more info.
1435+ import tkinter
1436+ from nltk .draw .table import Table
1437+
14311438 # Create the top-level frame structures
1432- f1 = Frame (self .top , relief = "raised" , border = 2 , padx = 8 , pady = 0 )
1439+ f1 = tkinter . Frame (self .top , relief = "raised" , border = 2 , padx = 8 , pady = 0 )
14331440 f1 .pack (sid = "top" , expand = True , fill = "both" )
14341441 f1 .grid_rowconfigure (2 , weight = 1 )
14351442 f1 .grid_columnconfigure (0 , weight = 1 )
1436- Frame (f1 , height = 8 ).grid (column = 0 , row = 0 ) # spacer
1437- tabframe = Frame (f1 )
1443+ tkinter . Frame (f1 , height = 8 ).grid (column = 0 , row = 0 ) # spacer
1444+ tabframe = tkinter . Frame (f1 )
14381445 tabframe .grid (column = 0 , row = 1 , sticky = "news" )
1439- tableframe = Frame (f1 )
1446+ tableframe = tkinter . Frame (f1 )
14401447 tableframe .grid (column = 0 , row = 2 , sticky = "news" )
1441- buttonframe = Frame (f1 )
1448+ buttonframe = tkinter . Frame (f1 )
14421449 buttonframe .grid (column = 0 , row = 3 , sticky = "news" )
1443- Frame (f1 , height = 8 ).grid (column = 0 , row = 4 ) # spacer
1444- infoframe = Frame (f1 )
1450+ tkinter . Frame (f1 , height = 8 ).grid (column = 0 , row = 4 ) # spacer
1451+ infoframe = tkinter . Frame (f1 )
14451452 infoframe .grid (column = 0 , row = 5 , sticky = "news" )
1446- Frame (f1 , height = 8 ).grid (column = 0 , row = 6 ) # spacer
1447- progressframe = Frame (
1453+ tkinter . Frame (f1 , height = 8 ).grid (column = 0 , row = 6 ) # spacer
1454+ progressframe = tkinter . Frame (
14481455 self .top , padx = 3 , pady = 3 , background = self ._BACKDROP_COLOR [1 ]
14491456 )
14501457 progressframe .pack (side = "bottom" , fill = "x" )
@@ -1455,7 +1462,7 @@ def _init_widgets(self):
14551462 self ._tab_names = ["Collections" , "Corpora" , "Models" , "All Packages" ]
14561463 self ._tabs = {}
14571464 for i , tab in enumerate (self ._tab_names ):
1458- label = Label (tabframe , text = tab , font = self ._TAB_FONT )
1465+ label = tkinter . Label (tabframe , text = tab , font = self ._TAB_FONT )
14591466 label .pack (side = "left" , padx = ((i + 1 ) % 2 ) * 10 )
14601467 label .bind ("<Button-1>" , self ._select_tab )
14611468 self ._tabs [tab .lower ()] = label
@@ -1492,8 +1499,8 @@ def _init_widgets(self):
14921499 ]
14931500 self ._info = {}
14941501 for i , (key , label , callback ) in enumerate (info ):
1495- Label (infoframe , text = label ).grid (column = 0 , row = i , sticky = "e" )
1496- entry = Entry (
1502+ tkinter . Label (infoframe , text = label ).grid (column = 0 , row = i , sticky = "e" )
1503+ entry = tkinter . Entry (
14971504 infoframe ,
14981505 font = "courier" ,
14991506 relief = "groove" ,
@@ -1510,23 +1517,23 @@ def _init_widgets(self):
15101517 self .top .bind ("<Button-1>" , self ._info_save )
15111518
15121519 # Create Download & Refresh buttons.
1513- self ._download_button = Button (
1520+ self ._download_button = tkinter . Button (
15141521 buttonframe , text = "Download" , command = self ._download , width = 8
15151522 )
15161523 self ._download_button .pack (side = "left" )
1517- self ._refresh_button = Button (
1524+ self ._refresh_button = tkinter . Button (
15181525 buttonframe , text = "Refresh" , command = self ._refresh , width = 8
15191526 )
15201527 self ._refresh_button .pack (side = "right" )
15211528
15221529 # Create Progress bar
1523- self ._progresslabel = Label (
1530+ self ._progresslabel = tkinter . Label (
15241531 progressframe ,
15251532 text = "" ,
15261533 foreground = self ._BACKDROP_COLOR [0 ],
15271534 background = self ._BACKDROP_COLOR [1 ],
15281535 )
1529- self ._progressbar = Canvas (
1536+ self ._progressbar = tkinter . Canvas (
15301537 progressframe ,
15311538 width = 200 ,
15321539 height = 16 ,
@@ -1539,9 +1546,11 @@ def _init_widgets(self):
15391546 self ._progresslabel .pack (side = "left" )
15401547
15411548 def _init_menu (self ):
1542- menubar = Menu (self .top )
1549+ import tkinter
1550+
1551+ menubar = tkinter .Menu (self .top )
15431552
1544- filemenu = Menu (menubar , tearoff = 0 )
1553+ filemenu = tkinter . Menu (menubar , tearoff = 0 )
15451554 filemenu .add_command (
15461555 label = "Download" , underline = 0 , command = self ._download , accelerator = "Return"
15471556 )
@@ -1567,9 +1576,9 @@ def _init_menu(self):
15671576 # Create a menu to control which columns of the table are
15681577 # shown. n.b.: we never hide the first two columns (mark and
15691578 # identifier).
1570- viewmenu = Menu (menubar , tearoff = 0 )
1579+ viewmenu = tkinter . Menu (menubar , tearoff = 0 )
15711580 for column in self ._table .column_names [2 :]:
1572- var = IntVar (self .top )
1581+ var = tkinter . IntVar (self .top )
15731582 assert column not in self ._column_vars
15741583 self ._column_vars [column ] = var
15751584 if column in self .INITIAL_COLUMNS :
@@ -1582,7 +1591,7 @@ def _init_menu(self):
15821591 # Create a sort menu
15831592 # [xx] this should be selectbuttons; and it should include
15841593 # reversed sorts as options.
1585- sortmenu = Menu (menubar , tearoff = 0 )
1594+ sortmenu = tkinter . Menu (menubar , tearoff = 0 )
15861595 for column in self ._table .column_names [1 :]:
15871596 sortmenu .add_command (
15881597 label = "Sort by %s" % column ,
@@ -1597,7 +1606,7 @@ def _init_menu(self):
15971606 )
15981607 menubar .add_cascade (label = "Sort" , underline = 0 , menu = sortmenu )
15991608
1600- helpmenu = Menu (menubar , tearoff = 0 )
1609+ helpmenu = tkinter . Menu (menubar , tearoff = 0 )
16011610 helpmenu .add_command (label = "About" , underline = 0 , command = self .about )
16021611 helpmenu .add_command (
16031612 label = "Instructions" , underline = 0 , command = self .help , accelerator = "F1"
@@ -1615,6 +1624,7 @@ def _select_columns(self):
16151624 self ._table .hide_column (column )
16161625
16171626 def _refresh (self ):
1627+ from tkinter .messagebox import showerror
16181628 self ._ds .clear_status_cache ()
16191629 try :
16201630 self ._fill_table ()
@@ -1661,6 +1671,7 @@ def _table_reprfunc(self, row, col, val):
16611671 return " %s" % val
16621672
16631673 def _set_url (self , url ):
1674+ from tkinter .messagebox import showerror
16641675 if url == self ._ds .url :
16651676 return
16661677 try :
@@ -1671,6 +1682,7 @@ def _set_url(self, url):
16711682 self ._show_info ()
16721683
16731684 def _set_download_dir (self , download_dir ):
1685+ from tkinter .messagebox import showerror
16741686 if self ._ds .download_dir == download_dir :
16751687 return
16761688 # check if the dir exists, and if not, ask if we should create it?
@@ -1696,6 +1708,7 @@ def _show_info(self):
16961708 entry ["state" ] = "disabled"
16971709
16981710 def _prev_tab (self , * e ):
1711+ from tkinter .messagebox import showerror
16991712 for i , tab in enumerate (self ._tab_names ):
17001713 if tab .lower () == self ._tab and i > 0 :
17011714 self ._tab = self ._tab_names [i - 1 ].lower ()
@@ -1707,6 +1720,7 @@ def _prev_tab(self, *e):
17071720 showerror ("Error connecting to server" , e .reason )
17081721
17091722 def _next_tab (self , * e ):
1723+ from tkinter .messagebox import showerror
17101724 for i , tab in enumerate (self ._tab_names ):
17111725 if tab .lower () == self ._tab and i < (len (self ._tabs ) - 1 ):
17121726 self ._tab = self ._tab_names [i + 1 ].lower ()
@@ -1718,6 +1732,7 @@ def _next_tab(self, *e):
17181732 showerror ("Error connecting to server" , e .reason )
17191733
17201734 def _select_tab (self , event ):
1735+ from tkinter .messagebox import showerror
17211736 self ._tab = event .widget ["text" ].lower ()
17221737 try :
17231738 self ._fill_table ()
@@ -1884,6 +1899,7 @@ def _table_mark(self, *e):
18841899 self ._table .select (delta = 1 )
18851900
18861901 def _show_log (self ):
1902+ from nltk .draw .util import ShowText
18871903 text = "\n " .join (self ._log_messages )
18881904 ShowText (self .top , "NLTK Downloader Log" , text )
18891905
@@ -1966,6 +1982,7 @@ def mainloop(self, *args, **kwargs):
19661982 )
19671983
19681984 def help (self , * e ):
1985+ from nltk .draw .util import ShowText
19691986 # The default font's not very legible; try using 'fixed' instead.
19701987 try :
19711988 ShowText (
@@ -1979,6 +1996,7 @@ def help(self, *e):
19791996 ShowText (self .top , "Help: NLTK Downloader" , self .HELP .strip (), width = 75 )
19801997
19811998 def about (self , * e ):
1999+ from nltk .draw .util import ShowText
19822000 ABOUT = "NLTK Downloader\n " + "Written by Edward Loper"
19832001 TITLE = "About: NLTK Downloader"
19842002 try :
0 commit comments