如何将字符串用于图标位图?
How to use a string for icon bitmap?
有没有办法在 Tkinter
(Python 2.7.9) 模块中为 iconbitmap
使用字符串?
我知道你可以提供一个文件路径(尽管我不明白 default
和 bitmap
作为参数的区别在哪里。
我问的原因是因为我想用 Python 脚本创建一个 .exe
和 py2exe
(可行),但我需要创建一个图标然后文件就可以使用图标了。
欢迎任何解决方法或其他方法。
(请注意使用 Python 3 的人,请参阅我的 以了解仅适用于该版本的替代方案。)
除了 Python 2.x 中的文件路径,我不知道有什么方法可以传递 iconbitmap()
任何东西,所以这里有一个从字符串创建临时文件的解决方法图标文件内容的表示以传递它。它还展示了一种确保临时文件被删除的方法。
import atexit
import binascii
import os
import tempfile
try:
import Tkinter as tk
except ModuleNotFoundError: # Python 3
import tkinter as tk
iconhexdata = '00000100010010100000010018006803000016000000280000001000000020' \
'000000010018000000000040030000130b0000130b00000000000000000000' \
'ffffff6c6c6d6c6c6d6c6c6d6c6c6d6c6c6d6c6c6d6c6c6d6c6c6d6c6c6d6c' \
'6c6d6c6c6d6c6c6d6c6c6d6c6c6dffffffffffff6c6c6d6c6c6d6c6c6d6c6c' \
'6d6c6c6d6c6c6d6c6c6d6c6c6d6c6c6d6c6c6d6c6c6d6c6c6d6c6c6d6c6c6d' \
'ffffffffffff6c6c6d6c6c6dffffffffffffffffffffffffffffffffffffff' \
'ffffffffffffffffffffff6c6c6d6c6c6dffffffffffff6c6c6d6c6c6dffff' \
'ff6c6c6d6c6c6d6c6c6d6c6c6d6c6c6d6c6c6d6c6c6d6c6c6dffffff6c6c6d' \
'6c6c6dffffffffffff6c6c6d6c6c6dffffff6c6c6d6c6c6d6c6c6d6c6c6d6c' \
'6c6d6c6c6d6c6c6d6c6c6dffffff6c6c6d6c6c6dffffffffffff6c6c6d6c6c' \
'6dfffffffffffffffffffffffffffffff2f4f7d6dfe9b8cadb95b2cfedf2f6' \
'6c6c6d6c6c6dfffffffffffffffffffffffff4f7fac0d4e69bb9d6739dc657' \
'89ba3e78b03f78af4177ad4276abd2deeaffffffffffffffffffffffffffff' \
'ffffffffdfe9f24178ad4178ad4178ad5081b17398be9db8d3bed4e6bbd7ec' \
'add7f3fffffffffffffffffffffffffffffffffffff8fafcaac2dac4d3e4df' \
'e8f1f9fbfdfffffff4fafd91cff520a3f10297eee4f4feffffffffffffffff' \
'ffffffffffffffffffffffffffffffffffffffe7f4fd7fcaf6159def0595ec' \
'179fec82c7f4bad6f7fdfefffffffffffffffffffffffffffffffffdfeffdb' \
'f0fd7bc8f6119bed0695eb1a9ded7ecaf5f0f8febfd3f73165e495b1f1ffff' \
'fffffffffffffffffffffffffff6fbfe2fa6ee0695eb1b9eed86ccf5e8f6fd' \
'ffffffd2dff93468e5326ae5c7d6f8ffffffffffffffffffffffffffffffff' \
'ffff96d2f784cbf5eaf6fdffffffffffffe3eafb4275e72c66e4b6caf6ffff' \
'ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff' \
'f3f6fd5784ea2c66e499b5f2ffffffffffffffffffffffffffffffffffffff' \
'fffffffffffffffffffffffffffffdfeff7097ed2c66e47a9eeeffffffffff' \
'fffffffffffffffffffffffffffffffffffffffffffffffffffffffffdfeff' \
'85a7ef2c66e4608cebf9fbfeffffffffffffffffffffffff00000000000000' \
'00000000000000000000000000000000000000000000000000000000000000' \
'0000000000000000000000000000000000000000000000000000'
def on_closing(iconfile):
try:
os.remove(iconfile.name)
except Exception:
pass
with tempfile.NamedTemporaryFile(delete=False) as iconfile:
iconfile.write(binascii.a2b_hex(iconhexdata))
# Register a clean-up function.
atexit.register(lambda file=iconfile: on_closing(file))
root = tk.Tk()
root.title('Whosebug!')
root.iconbitmap(iconfile.name)
tk.Label(root, text='Note the custom icon').pack()
tk.Button(root, text='OK', bg='lightgreen', command=root.quit).pack()
root.mainloop()
显示的window会有自定义图标,如下图:
你没有问怎么做,但这是我用来将原始 .ico
文件转换为我的示例中使用的 Python 字符串变量的代码:
from __future__ import print_function
import binascii
try:
from itertools import izip_longest as zip_longest
except ImportError:
from itertools import zip_longest
iconfile = 'Whosebug.ico' # Path to icon file.
VAR_NAME = 'iconhexdata'
VAR_SUFFIX = ' = '
INDENTATION = ' ' * len(VAR_NAME+VAR_SUFFIX)
MAX_LINE_LENGTH = 80
EXTRA_CHARS = '"" \' # That get added to each group of hex digits.
LINE_LENGTH = MAX_LINE_LENGTH - len(INDENTATION) - len(EXTRA_CHARS)
def grouper(chunk_size, iterable):
""" Collect data into fixed-length chunks or blocks.
s -> (s0,s1,...sn-1), (sn,sn+1,...s2n-1), (s2n,s2n+1,...s3n-1), ...
"""
return zip_longest(*[iter(iterable)]*chunk_size, fillvalue='')
with open(iconfile, 'rb') as imgfile:
hexstr = [chr(x) for x in bytearray(binascii.b2a_hex(imgfile.read()))]
hexlines = (''.join(str(x) for x in group) for group in grouper(LINE_LENGTH, hexstr))
print(VAR_NAME + VAR_SUFFIX, end='')
print((' \\n' + INDENTATION).join((repr(line) for line in hexlines)))
这不会回答您的 Python 2.7 问题,但现在使用 Python 3 的其他人可能会感兴趣。在 Python 的更高版本中,tkinter
模块有一个替代 iconbitmap()
函数的方法——名为 iconphoto()
——可用于设置任何 tkinter/toplevel window。但是,与前一种方法不同的是,图像应该是 tkinter.PhotoImage
class 的实例,而不仅仅是文件路径字符串 — 还有 和 种从程序中的字节字符串创建 PhotoImage
对象的方法,因此根本不需要使用文件,即使是像我最初的回答中那样的临时文件。
#!/usr/bin/env python3
iconimgdata = b'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAAGXRFWHRTb2Z0d' \
b'2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAXpJREFUeNpi+I8V/Pv7fnnrkz' \
b'Sd1z0J/37/RJZhYsAKGJkEwis4DV1+3jrzYXEjsgwODRA98c1sctrfTmz6vG0' \
b'WQhzNLd8vTft6uuXvt1cQ7u9Xj5+XOgHd9u3UNogIioZ/v7+9W6b/eirb23nS' \
b'X8+0/f32Aij48/6lpxkmT7OMflw7ju4HRmZ2fq813MalDH+/fTvZ8GG50bfT9' \
b'aySckLZ3f9///95+xxIDcgWDPDv64uf12b8vDzt748PDFxCHBrZzPwWHBrOQI' \
b'8hNPz9/fPeiU1cglK8otI8wlJMLGz/fn/9cXXunyv9f788Eoh9xMgtDVTGAjf' \
b'12/vnl7dNh7BZOPl5xZVFFbSEZXTZTGazM3yCqEZx0u8fX9/cPfPh6e0PT258' \
b'efMEqP8/A+O//0z//jPaZ0wQVdRFaMjLzQWyJk2ejOyNH18/f3r95NPrR19e3' \
b'FV3iCivqoeoYUFWBNGJCSb5ChER0zgAig1oriKgAZd70ADJTgIIMACVtvtL6F' \
b'X2cAAAAABJRU5ErkJggg=='
import base64
import tkinter as tk # Python 3
root = tk.Tk()
root.title('Whosebug!')
root.geometry('225x50')
img = base64.b64decode(iconimgdata)
photo = tk.PhotoImage(data=img)
root.iconphoto(False, photo)
tk.Label(root, text='Note the custom icon').pack()
tk.Button(root, text='OK', bg='lightgreen', command=root.quit).pack()
root.mainloop()
这是演示的样子 运行:
这又是我用来将我拥有的 16x16 像素 .png
图像文件转换为上面示例代码中使用的 Python bytestring
变量的代码。这是正在使用的 Whosebug.png
小图像文件的 link。
#!/usr/bin/env python3
import base64
from itertools import zip_longest
imgfilepath = 'Whosebug.png' # Path to an image file.
VAR_NAME = 'iconimgdata'
VAR_SUFFIX = ' = '
INDENTATION = ' ' * len(VAR_NAME+VAR_SUFFIX)
MAX_LINE_LENGTH = 79
EXTRA_CHARS = '"" \' # That get added to each group of hex digits.
LINE_LENGTH = MAX_LINE_LENGTH - len(INDENTATION) - len(EXTRA_CHARS)
def grouper(chunk_size, iterable):
""" Collect data into fixed-length chunks or blocks.
s -> (s0,s1,...sn-1), (sn,sn+1,...s2n-1), (s2n,s2n+1,...s3n-1), ...
"""
return zip_longest(*[iter(iterable)]*chunk_size, fillvalue='')
with open(imgfilepath, 'rb') as file:
hexstr = [chr(x) for x in base64.b64encode(file.read())]
hexlines = (''.join(str(x) for x in group) for group in grouper(LINE_LENGTH, hexstr))
print(VAR_NAME + VAR_SUFFIX + 'b', end='')
print((' \\n' + INDENTATION + 'b').join((repr(line) for line in hexlines)))
有没有办法在 Tkinter
(Python 2.7.9) 模块中为 iconbitmap
使用字符串?
我知道你可以提供一个文件路径(尽管我不明白 default
和 bitmap
作为参数的区别在哪里。
我问的原因是因为我想用 Python 脚本创建一个 .exe
和 py2exe
(可行),但我需要创建一个图标然后文件就可以使用图标了。
欢迎任何解决方法或其他方法。
(请注意使用 Python 3 的人,请参阅我的
除了 Python 2.x 中的文件路径,我不知道有什么方法可以传递 iconbitmap()
任何东西,所以这里有一个从字符串创建临时文件的解决方法图标文件内容的表示以传递它。它还展示了一种确保临时文件被删除的方法。
import atexit
import binascii
import os
import tempfile
try:
import Tkinter as tk
except ModuleNotFoundError: # Python 3
import tkinter as tk
iconhexdata = '00000100010010100000010018006803000016000000280000001000000020' \
'000000010018000000000040030000130b0000130b00000000000000000000' \
'ffffff6c6c6d6c6c6d6c6c6d6c6c6d6c6c6d6c6c6d6c6c6d6c6c6d6c6c6d6c' \
'6c6d6c6c6d6c6c6d6c6c6d6c6c6dffffffffffff6c6c6d6c6c6d6c6c6d6c6c' \
'6d6c6c6d6c6c6d6c6c6d6c6c6d6c6c6d6c6c6d6c6c6d6c6c6d6c6c6d6c6c6d' \
'ffffffffffff6c6c6d6c6c6dffffffffffffffffffffffffffffffffffffff' \
'ffffffffffffffffffffff6c6c6d6c6c6dffffffffffff6c6c6d6c6c6dffff' \
'ff6c6c6d6c6c6d6c6c6d6c6c6d6c6c6d6c6c6d6c6c6d6c6c6dffffff6c6c6d' \
'6c6c6dffffffffffff6c6c6d6c6c6dffffff6c6c6d6c6c6d6c6c6d6c6c6d6c' \
'6c6d6c6c6d6c6c6d6c6c6dffffff6c6c6d6c6c6dffffffffffff6c6c6d6c6c' \
'6dfffffffffffffffffffffffffffffff2f4f7d6dfe9b8cadb95b2cfedf2f6' \
'6c6c6d6c6c6dfffffffffffffffffffffffff4f7fac0d4e69bb9d6739dc657' \
'89ba3e78b03f78af4177ad4276abd2deeaffffffffffffffffffffffffffff' \
'ffffffffdfe9f24178ad4178ad4178ad5081b17398be9db8d3bed4e6bbd7ec' \
'add7f3fffffffffffffffffffffffffffffffffffff8fafcaac2dac4d3e4df' \
'e8f1f9fbfdfffffff4fafd91cff520a3f10297eee4f4feffffffffffffffff' \
'ffffffffffffffffffffffffffffffffffffffe7f4fd7fcaf6159def0595ec' \
'179fec82c7f4bad6f7fdfefffffffffffffffffffffffffffffffffdfeffdb' \
'f0fd7bc8f6119bed0695eb1a9ded7ecaf5f0f8febfd3f73165e495b1f1ffff' \
'fffffffffffffffffffffffffff6fbfe2fa6ee0695eb1b9eed86ccf5e8f6fd' \
'ffffffd2dff93468e5326ae5c7d6f8ffffffffffffffffffffffffffffffff' \
'ffff96d2f784cbf5eaf6fdffffffffffffe3eafb4275e72c66e4b6caf6ffff' \
'ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff' \
'f3f6fd5784ea2c66e499b5f2ffffffffffffffffffffffffffffffffffffff' \
'fffffffffffffffffffffffffffffdfeff7097ed2c66e47a9eeeffffffffff' \
'fffffffffffffffffffffffffffffffffffffffffffffffffffffffffdfeff' \
'85a7ef2c66e4608cebf9fbfeffffffffffffffffffffffff00000000000000' \
'00000000000000000000000000000000000000000000000000000000000000' \
'0000000000000000000000000000000000000000000000000000'
def on_closing(iconfile):
try:
os.remove(iconfile.name)
except Exception:
pass
with tempfile.NamedTemporaryFile(delete=False) as iconfile:
iconfile.write(binascii.a2b_hex(iconhexdata))
# Register a clean-up function.
atexit.register(lambda file=iconfile: on_closing(file))
root = tk.Tk()
root.title('Whosebug!')
root.iconbitmap(iconfile.name)
tk.Label(root, text='Note the custom icon').pack()
tk.Button(root, text='OK', bg='lightgreen', command=root.quit).pack()
root.mainloop()
显示的window会有自定义图标,如下图:
你没有问怎么做,但这是我用来将原始 .ico
文件转换为我的示例中使用的 Python 字符串变量的代码:
from __future__ import print_function
import binascii
try:
from itertools import izip_longest as zip_longest
except ImportError:
from itertools import zip_longest
iconfile = 'Whosebug.ico' # Path to icon file.
VAR_NAME = 'iconhexdata'
VAR_SUFFIX = ' = '
INDENTATION = ' ' * len(VAR_NAME+VAR_SUFFIX)
MAX_LINE_LENGTH = 80
EXTRA_CHARS = '"" \' # That get added to each group of hex digits.
LINE_LENGTH = MAX_LINE_LENGTH - len(INDENTATION) - len(EXTRA_CHARS)
def grouper(chunk_size, iterable):
""" Collect data into fixed-length chunks or blocks.
s -> (s0,s1,...sn-1), (sn,sn+1,...s2n-1), (s2n,s2n+1,...s3n-1), ...
"""
return zip_longest(*[iter(iterable)]*chunk_size, fillvalue='')
with open(iconfile, 'rb') as imgfile:
hexstr = [chr(x) for x in bytearray(binascii.b2a_hex(imgfile.read()))]
hexlines = (''.join(str(x) for x in group) for group in grouper(LINE_LENGTH, hexstr))
print(VAR_NAME + VAR_SUFFIX, end='')
print((' \\n' + INDENTATION).join((repr(line) for line in hexlines)))
这不会回答您的 Python 2.7 问题,但现在使用 Python 3 的其他人可能会感兴趣。在 Python 的更高版本中,tkinter
模块有一个替代 iconbitmap()
函数的方法——名为 iconphoto()
——可用于设置任何 tkinter/toplevel window。但是,与前一种方法不同的是,图像应该是 tkinter.PhotoImage
class 的实例,而不仅仅是文件路径字符串 — 还有 和 种从程序中的字节字符串创建 PhotoImage
对象的方法,因此根本不需要使用文件,即使是像我最初的回答中那样的临时文件。
#!/usr/bin/env python3
iconimgdata = b'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAAGXRFWHRTb2Z0d' \
b'2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAXpJREFUeNpi+I8V/Pv7fnnrkz' \
b'Sd1z0J/37/RJZhYsAKGJkEwis4DV1+3jrzYXEjsgwODRA98c1sctrfTmz6vG0' \
b'WQhzNLd8vTft6uuXvt1cQ7u9Xj5+XOgHd9u3UNogIioZ/v7+9W6b/eirb23nS' \
b'X8+0/f32Aij48/6lpxkmT7OMflw7ju4HRmZ2fq813MalDH+/fTvZ8GG50bfT9' \
b'aySckLZ3f9///95+xxIDcgWDPDv64uf12b8vDzt748PDFxCHBrZzPwWHBrOQI' \
b'8hNPz9/fPeiU1cglK8otI8wlJMLGz/fn/9cXXunyv9f788Eoh9xMgtDVTGAjf' \
b'12/vnl7dNh7BZOPl5xZVFFbSEZXTZTGazM3yCqEZx0u8fX9/cPfPh6e0PT258' \
b'efMEqP8/A+O//0z//jPaZ0wQVdRFaMjLzQWyJk2ejOyNH18/f3r95NPrR19e3' \
b'FV3iCivqoeoYUFWBNGJCSb5ChER0zgAig1oriKgAZd70ADJTgIIMACVtvtL6F' \
b'X2cAAAAABJRU5ErkJggg=='
import base64
import tkinter as tk # Python 3
root = tk.Tk()
root.title('Whosebug!')
root.geometry('225x50')
img = base64.b64decode(iconimgdata)
photo = tk.PhotoImage(data=img)
root.iconphoto(False, photo)
tk.Label(root, text='Note the custom icon').pack()
tk.Button(root, text='OK', bg='lightgreen', command=root.quit).pack()
root.mainloop()
这是演示的样子 运行:
这又是我用来将我拥有的 16x16 像素 .png
图像文件转换为上面示例代码中使用的 Python bytestring
变量的代码。这是正在使用的 Whosebug.png
小图像文件的 link。
#!/usr/bin/env python3
import base64
from itertools import zip_longest
imgfilepath = 'Whosebug.png' # Path to an image file.
VAR_NAME = 'iconimgdata'
VAR_SUFFIX = ' = '
INDENTATION = ' ' * len(VAR_NAME+VAR_SUFFIX)
MAX_LINE_LENGTH = 79
EXTRA_CHARS = '"" \' # That get added to each group of hex digits.
LINE_LENGTH = MAX_LINE_LENGTH - len(INDENTATION) - len(EXTRA_CHARS)
def grouper(chunk_size, iterable):
""" Collect data into fixed-length chunks or blocks.
s -> (s0,s1,...sn-1), (sn,sn+1,...s2n-1), (s2n,s2n+1,...s3n-1), ...
"""
return zip_longest(*[iter(iterable)]*chunk_size, fillvalue='')
with open(imgfilepath, 'rb') as file:
hexstr = [chr(x) for x in base64.b64encode(file.read())]
hexlines = (''.join(str(x) for x in group) for group in grouper(LINE_LENGTH, hexstr))
print(VAR_NAME + VAR_SUFFIX + 'b', end='')
print((' \\n' + INDENTATION + 'b').join((repr(line) for line in hexlines)))