<edited> Python 2.7 tkinter(和IDLE)“问题”

时间:2017-03-31 16:49:55

标签: python python-2.7 tkinter python-idle

当我使用Python IDLE时,我遇到了一些基于tkinter的问题。

首先,无法在我的电脑中打开IDLE

我使用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吗?

这是一种错误吗?

其次,我的朋友无法改变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。

1 个答案:

答案 0 :(得分:0)

关于第二个问题,我认为与第一个问题无关。我真的不明白代码引用的问题或重点。

IDLE有一个通过菜单访问的选项设置对话框。初始(和默认)选项卡的字体大小设置一直适用于我(在Windows上)。 “如何更改字体大小?”的答案是使用预期的字体大小更改小部件。

我只是用2.7.13重新检查它仍然适用于我。 2.7.11中存在一个错误,表现为无法在某些Linux系统上打开对话框。但这在2.7.12中已得到修复。我检查了2.7.13补丁列表,没有一个应该影响字体大小。不过,就IDLE而言,我建议升级。