Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1""" 

2@file 

3@brief Helpers for tkinter 

4""" 

5import os 

6import sys 

7import warnings 

8import ctypes 

9 

10_first_execution = False 

11 

12 

13def fix_tkinter_issues_virtualenv(exc=True, fLOG=None): 

14 """ 

15 Fix an issue which happens in a virtual environment, 

16 see `Fix Tcl inside a virtualenv on Windows <https://github.com/pypa/virtualenv/pull/627>`_ 

17 

18 @param exc raise an exception instead of a warning 

19 @param fLOG logging function 

20 @return list of environment variables 

21 

22 We try to deal with the following issue on Linux:: 

23 

24 _tkinter.TclError: no display name and no $DISPLAY 

25 

26 On Linux, the solution is to run:: 

27 

28 import matplotlib as mpl 

29 mpl.use('Agg') 

30 

31 But it does not work if matplotlib was already imported. 

32 It is recommended to delay its import 

33 whenever it is possible. 

34 """ 

35 global _first_execution 

36 

37 def location(): # pragma: no cover 

38 site = os.path.normpath(os.path.dirname( 

39 os.path.join(os.path.abspath(ctypes.__file__)))) 

40 rev = os.path.join(site, "..", "..") 

41 if sys.platform.startswith("win"): 

42 site = os.path.join(rev, "tcl") 

43 if not os.path.exists(site): 

44 site2 = os.path.join(rev, "..", "tcl") 

45 if os.path.exists(site2): 

46 site = site2 

47 else: 

48 mes = ", ".join(os.listdir(rev)) 

49 raise FileNotFoundError( 

50 "Unable to find: {0},\nsubfolders: {1}".format(site, mes)) 

51 else: 

52 site = os.path.join(rev, "..", "tcl") 

53 if not os.path.exists(site): 

54 mes = ", ".join(os.listdir(os.path.join(rev, ".."))) 

55 raise FileNotFoundError( 

56 "unable to find: {0},\nsubfolders: {1}".format(site, mes)) 

57 return os.path.normpath(site) 

58 

59 def look_for(where, prefix): # pragma: no cover 

60 lst = sorted(os.listdir(where), reverse=True) 

61 lp = len(prefix) 

62 for _ in lst: 

63 if _.startswith(prefix) and "0" <= _[lp] <= "9" and ".lib" not in _: 

64 return os.path.join(where, _) 

65 raise FileNotFoundError("Unable to find any folder starting with {0} in {1}\nLIST:\n{2}".format( 

66 prefix, where, ", ".join(lst))) 

67 

68 if sys.platform.startswith("win"): # pragma: no cover 

69 if "matplotlib" in sys.modules: 

70 if _first_execution: 

71 warnings.warn( 

72 "Cannot fix matplotlib display because it was already imported.", UserWarning) 

73 if exc: 

74 raise Exception( 

75 "Cannot fix matplotlib display because it was already imported.") 

76 

77 if "TCL_LIBRARY" not in os.environ: 

78 loc = location() 

79 p = look_for(loc, "tcl") 

80 if fLOG: 

81 fLOG("[fix_tkinter_issues_virtualenv] Change {0}: '{1}' --> '{2}'".format("TCL_LIBRARY", 

82 os.environ.get("TCL_LIBRARY", None), p)) 

83 os.environ["TCL_LIBRARY"] = p 

84 if fLOG: 

85 fLOG("[fix_tkinter_issues_virtualenv] TCL_LIBRARY='{0}'".format( 

86 os.environ["TCL_LIBRARY"])) 

87 

88 if "TK_LIBRARY" not in os.environ: 

89 loc = location() 

90 p = look_for(loc, "tk") 

91 if fLOG: 

92 fLOG("[fix_tkinter_issues_virtualenv] Change {0}: '{1}' --> '{2}'".format("TK_LIBRARY", 

93 os.environ.get("TK_LIBRARY", None), p)) 

94 os.environ["TK_LIBRARY"] = p 

95 if fLOG: 

96 fLOG("[fix_tkinter_issues_virtualenv] TK_LIBRARY='{0}'".format( 

97 os.environ["TK_LIBRARY"])) 

98 

99 if "TIX_LIBRARY" not in os.environ: 

100 loc = location() 

101 p = look_for(loc, "tix") 

102 if fLOG: 

103 fLOG("[fix_tkinter_issues_virtualenv] Change {0}: '{1}' --> '{2}'".format("TIX_LIBRARY", 

104 os.environ.get("TIX_LIBRARY", None), p)) 

105 os.environ["TIX_LIBRARY"] = p 

106 if fLOG: 

107 fLOG("[fix_tkinter_issues_virtualenv] TIX_LIBRARY='{0}'".format( 

108 os.environ["TIX_LIBRARY"])) 

109 

110 if "DISPLAY" not in os.environ: 

111 p = ":0" 

112 if fLOG: 

113 fLOG("Change {0}: '{1}' --> '{2}'".format("DISPLAY", 

114 os.environ.get("DISPLAY", None), p)) 

115 os.environ["DISPLAY"] = p 

116 else: 

117 # if "DISPLAY" not in os.environ: 

118 # os.environ["DISPLAY"] = ':10.0' 

119 if fLOG: 

120 fLOG("[fix_tkinter_issues_virtualenv] Call mpl.use('Agg')") 

121 if "matplotlib" in sys.modules: 

122 if _first_execution: 

123 warnings.warn( # pragma: no cover 

124 "Cannot fix matplotlib display because it was already imported.", UserWarning) 

125 if exc: 

126 raise Exception( # pragma: no cover 

127 "Cannot fix matplotlib display because it was already imported.") 

128 import matplotlib as mpl 

129 mpl.use('Agg') 

130 else: # pragma: no cover 

131 import matplotlib as mpl 

132 mpl.use('Agg') 

133 

134 _first_execution = False 

135 

136 return os.environ.get("TCL_LIBRARY", None), os.environ.get("TK_LIBRARY", None), \ 

137 os.environ.get("TIX_LIBRARY", None), os.environ.get("DISPLAY", None)