我正在使用
Python 3.11
并且我制作了一个 Markdown 阅读器程序。
我使用
iconbitmap
东西在 Tkinter 窗口上放置了一个图标,当我运行 Python 文件时,一切都运行良好。
但是,当我将其作为可执行文件运行(使用
cxfreeze
制作)并打开一个 markdown 文件时,它向我返回了此错误:
看起来它无法调用
iconbitmap
事物或者无法访问 icon.ico
。
这是我的代码:
import tkinter as tk
import tkinter.filedialog as FileDialog
from tkhtmlview import HTMLLabel
import markdown
import sys
import os
dir_name = os.path.dirname(__file__)
dir_name = dir_name.replace("\\", "\\\\")
icon_dir = dir_name + "\\\\icon.ico"
def display_markdown(markdown_text):
# Convert Markdown to HTML
html_content = markdown.markdown(markdown_text)
# Create the Tkinter window
window = tk.Tk()
window.iconbitmap(icon_dir)
window.title("Markdown Reader")
# Create an HTMLLabel to display the HTML content
html_label = HTMLLabel(window, html=html_content)
html_label.pack(expand=True, fill="both")
# Run the Tkinter main loop
window.mainloop()
def display_markdown_from_file(file_path):
with open(file_path, 'r', encoding='utf-8') as file:
markdown_text = file.read()
display_markdown(markdown_text)
if __name__ == "__main__":
if len(sys.argv) == 2:
display_markdown_from_file(sys.argv[1])
else:
file = FileDialog.askopenfile(mode="r", filetypes=[("Markdown Files", "*.md *.markdown")], title="Open Markdown File")
if file is not None:
content = file.read()
display_markdown(content)
如果我们打印路径,问题就会变得更清楚。
...
import sys
import os
dir_name = os.path.dirname(__file__)
dir_name = dir_name.replace("\\", "\\\\")
icon_dir = dir_name + "\\\\icon.ico"
print(__file__)
print("dir_name", dir_name)
print("icon_dir", icon_dir)
...
注意:图标文件 (icon.ico) 与 Python 脚本位于同一目录中。我已经简化了您的程序,使其仅接受参数并显示 GUI。
Python 文件:
(env) F:\cxexe>test.py qwerty
F:\cxexe\test.py
dir_name F:\\cxexe
icon_dir F:\\cxexe\\icon.ico
exe 的输出:
(env) F:\cxexe>cxfreeze -c test.py --target-dir dist --include-files icon.ico
(env) F:\cxexe>cd dist
(env) F:\cxexe\dist>test.exe qwerty
test.py
dir_name
icon_dir \\icon.ico
Traceback (most recent call last):
...
return self.tk.call('wm', 'iconbitmap', self._w, bitmap)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
_tkinter.TclError: bitmap "\\icon.ico" not defined
正如我们所见,dir_name 现在是一个空字符串。
文件名中的反斜杠变得多余。
>>> import os
>>> path = "test.py" # __file__
>>> os.path.split(path)
('', 'test.py')
>>> os.path.dirname(path)
''
>>> print(os.path.dirname(path) + "\\\\icon.ico")
\\icon.ico
...
dir_name = os.path.dirname(__file__)
icon_file = "icon.ico"
def display_markdown(markdown_text):
...
window.iconbitmap(os.path.join(dir_name, icon_file))
...
...
import sys
import os
icon_file = "icon.ico"
def find_data_file(filename):
if getattr(sys, "frozen", False):
# The application is frozen
datadir = os.path.dirname(sys.executable)
else:
# The application is not frozen
# Change this bit to match where you store your data files:
datadir = os.path.dirname(__file__)
return os.path.join(datadir, filename)
def display_markdown(markdown_text):
...
window.iconbitmap(find_data_file(icon_file))
...