当我使用Python IDLE时,我遇到了一些基于tkinter的问题。
我使用Python 2.7.12。
通过windows命令行打开IDLE后,我发现了问题所在。
这是在Tkinter:
###C:\Python27\Lib\lib-tk\Tkinter.py
##Line:80
value = unicode(value, 'utf-8')
这失败了:
Traceback (most recent call last):
File "C:\Python27\lib\lib-tk\Tkinter.py", line 80, in _stringify
value = unicode(value, 'utf-8')
UnicodeDecodeError: 'utf8' codec can't decode byte 0xb2 in position 0: invalid start byte
所以我把它改成了:
###C:\Python27\Lib\lib-tk\Tkinter.py
##Line:80
value = unicode(value, 'cp950')
然后它现在工作正常,但每个人都必须在使用它之前修改它们的IDLE吗?
这是一种错误吗?
这是我的调试说明:
###C:\Python27\Lib\idlelib\idle.py
##Ln:10
import idlelib.PyShell
idlelib.PyShell.main()
###C:\Python27\Lib\idlelib\PyShell.py
##Ln:1475
def main():
global flist, root, use_subprocess
##Ln:1552 in function main
# start editor and/or shell windows:
root = Tk(className="Idle")
root.withdraw()
##Ln:1570 in function main
flist = PyShellFileList(root)
##Ln:312
class PyShellFileList(FileList):
"Extend base class: IDLE supports a shell and breakpoints"
# override FileList's class variable, instances return PyShellEditorWindow
# instead of EditorWindow when new edit windows are created.
EditorWindow = PyShellEditorWindow
###C:\Python27\Lib\idlelib\FileList.py
##Ln:6
class FileList:
# N.B. this import overridden in PyShellFileList.
from idlelib.EditorWindow import EditorWindow
###C:\Python27\Lib\idlelib\PyShell.py
##Ln:125
class PyShellEditorWindow(EditorWindow):
"Regular text edit window in IDLE, supports breakpoints"
def __init__(self, *args):
self.breakpoints = []
EditorWindow.__init__(self, *args)
###C:\Python27\Lib\idlelib\PyShell.py
##Ln:262 in class EditorWindow
text['font'] = idleConf.GetFont(self.root, 'main', 'EditorWindow')
###C:\Python27\Lib\idlelib\configHandler.py
##Ln:700 in class IdleConf
def GetFont(self, root, configType, section):
"""Retrieve a font from configuration (font, font-size, font-bold)
Intercept the special value 'TkFixedFont' and substitute
the actual font, factoring in some tweaks if needed for
appearance sakes.
The 'root' parameter can normally be any valid Tkinter widget.
Return a tuple (family, size, weight) suitable for passing
to tkinter.Font
"""
family = self.GetOption(configType, section, 'font', default='courier')
size = self.GetOption(configType, section, 'font-size', type='int',
default='10')
bold = self.GetOption(configType, section, 'font-bold', default=0,
type='bool')
if (family == 'TkFixedFont'):
if TkVersion < 8.5:
family = 'Courier'
else:
f = Font(name='TkFixedFont', exists=True, root=root)
actualFont = Font.actual(f)
family = actualFont['family']
size = actualFont['size']
if size <= 0:
size = 10 # if font in pixels, ignore actual size
bold = actualFont['weight']=='bold'
return (family, size, 'bold' if bold else 'normal')
###C:\Python27\Lib\lib-tk\tkFont.py
##Ln:66 in class Font
def __init__(self, root=None, font=None, name=None, exists=False, **options):
if not root:
root = Tkinter._default_root
tk = getattr(root, 'tk', root)
##Ln:92 in class Font in method __init__
self._split = tk.splitlist
self._call = tk.call
##Ln:120 in class Font
def actual(self, option=None):
"Return actual font attributes"
if option:
return self._call("font", "actual", self.name, "-"+option)
else:
return self._mkdict(
self._split(self._call("font", "actual", self.name))
)
##Ln:60 in class Font
def _mkdict(self, args):
options = {}
for i in range(0, len(args), 2):
options[args[i][1:]] = args[i+1]
return options
所以问题是Tkinter ......再次。我做了一个小测试:
import Tkinter
root=Tkinter.Tk()
def _mkdict(args):
options = {}
for i in range(0, len(args), 2):
options[args[i][1:]] = args[i+1]
return options
resulta=_mkdict(root.tk.splitlist(root.tk.call("font","actual","TkFixedFont")))
print "a",resulta
resultb=_mkdict(root.tk.splitlist(root.tk.call("font","actual","細明體")))
print "b",resultb
然后我得到了:
a {'family': u'\u7d30\u660e\u9ad4', 'weight': 'normal', 'slant': 'roman', 'overstrike': 0, 'underline': 0, 'size': 10}
b {'family': u'\u65b0\u7d30\u660e\u9ad4', 'weight': 'normal', 'slant': 'roman', 'overstrike': 0, 'underline': 0, 'size': 15}
问题出在tkFont.Font的实际模块中?还是...?
也许我没有很好地描述第二个“问题”,也许我给出了太多细节,所以这是第二个问题的核心:
###C:\Python27\Lib\idlelib\configHandler.py
##Ln:700 in class IdleConf
def GetFont(self, root, configType, section):
"""Retrieve a font from configuration (font, font-size, font-bold)
Intercept the special value 'TkFixedFont' and substitute
the actual font, factoring in some tweaks if needed for
appearance sakes.
The 'root' parameter can normally be any valid Tkinter widget.
Return a tuple (family, size, weight) suitable for passing
to tkinter.Font
"""
family = self.GetOption(configType, section, 'font', default='courier')
size = self.GetOption(configType, section, 'font-size', type='int',
default='10')
bold = self.GetOption(configType, section, 'font-bold', default=0,
type='bool')
if (family == 'TkFixedFont'):
if TkVersion < 8.5:
family = 'Courier'
else:
f = Font(name='TkFixedFont', exists=True, root=root)
actualFont = Font.actual(f)
family = actualFont['family']
size = actualFont['size']
if size <= 0:
size = 10 # if font in pixels, ignore actual size
bold = actualFont['weight']=='bold'
return (family, size, 'bold' if bold else 'normal')
如果字体系列不是“TkFixedFont”,则getFont将返回正确的大小,该大小由用户在“configure IDLE”面板中配置。
但是如果字体系列是“TkFixedFont”,它将忽略用户的设置并使用“actualFont ['size']”,这是我测试的10。
答案 0 :(得分:0)
关于第二个问题,我认为与第一个问题无关。我真的不明白代码引用的问题或重点。
IDLE有一个通过菜单访问的选项设置对话框。初始(和默认)选项卡的字体大小设置一直适用于我(在Windows上)。 “如何更改字体大小?”的答案是使用预期的字体大小更改小部件。
我只是用2.7.13重新检查它仍然适用于我。 2.7.11中存在一个错误,表现为无法在某些Linux系统上打开对话框。但这在2.7.12中已得到修复。我检查了2.7.13补丁列表,没有一个应该影响字体大小。不过,就IDLE而言,我建议升级。