制作为可执行文件时在 Tkinter 窗口中包含图标

问题描述 投票:0回答:1

我正在使用

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)

python tkinter markdown executable
1个回答
0
投票

如果我们打印路径,问题就会变得更清楚。

...
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

os.path.dirname


解决方案



  1. os.path.join
...
dir_name = os.path.dirname(__file__)
icon_file = "icon.ico"

def display_markdown(markdown_text):
    ...
    window.iconbitmap(os.path.join(dir_name, icon_file))
    ...


  1. 文档推荐
...
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))
    ...

文档

另一个样本


© www.soinside.com 2019 - 2024. All rights reserved.