18.python打包win32print时报错,说找不到该模块
相关插件自己提前安装好。
代码:
1 #encoding:utf-8 2 3 from tkinter import * 4 from tkinter import messagebox 5 import win32print 6 import time 7 from tkinter import scrolledtext 8 9 # 控制输入框只能输入数字且小于8位数 10 def validate_op(input_text): 11 if input_text.isdigit() or input_text == "": 12 if len(input_text) <= 8: 13 return True 14 return False 15 16 # 控制输入框只能输入数字且小于4位数 17 def validate_password(input_text): 18 if input_text.isdigit() or input_text == "": 19 if len(input_text) <= 4: 20 return True 21 return False 22 23 24 def get_printers(): 25 printers = win32print.EnumPrinters(win32print.PRINTER_ENUM_LOCAL | win32print.PRINTER_ENUM_CONNECTIONS) 26 printer_list = [] 27 for printer in printers: 28 printer_name = printer[2] 29 printer_list.append(printer_name) 30 return printer_list 31 32 class Application(Frame): 33 def __init__(self, master=None): 34 super().__init__(master) 35 self.master = master 36 self.pack() 37 38 self.createWidget() 39 40 def createWidget(self): 41 self.utk_l_title = Label(root,text="OBA RM LABEL 列印指令生成",bg="red",font=("Arial",16),width=30,height=2).pack() 42 self.utk_l_DB = Label(root,text="请选择打印机:",font=("Arial",16)).place(x = 30,y = 70) 43 #创建一个选择数据库下拉框 44 45 46 PSHDB = ["请选择打印机"] 47 # 调用函数获取打印机列表 48 printer_list = get_printers() 49 # 打印机列表打印输出 50 for printer in printer_list: 51 # print(printer) 52 PSHDB.append(printer) 53 self.PSHDBVariable = StringVar() 54 self.PSHDBVariable.set(PSHDB[0]) 55 self.utk_o_DB = OptionMenu(root,self.PSHDBVariable, *PSHDB).place(x = 180,y = 70) 56 #创建一个工号标签 57 self.utk_l_op = Label(root,text="开始序号:",font=("Arial",16)).place(x = 30,y = 120) 58 self.utk_l_op1 = Label(root, text="【年份+日期+0000】如 23080000", font=("Arial", 12)).place(x=290, y=125) 59 #创建一个工号输入框 60 # self.utk_e_op=Entry(root) 61 self.utk_e_op = Entry(root, validate="key", validatecommand=(root.register(validate_op), '%P')) 62 self.utk_e_op.place(x = 150,y = 125) 63 self.utk_e_op.bind("<Return>", self.clear_entry) 64 #创建一个密码标签 65 self.utk_l_password = Label(root,text="打印数量:",font=("Arial",16)).place(x = 30,y = 170) 66 self.utk_l_password1 = Label(root, text="【1~1000】", font=("Arial", 12)).place(x=290, y=170) 67 #创建一个密码输入框 68 self.utk_e_password = Entry(root, validate="key", validatecommand=(root.register(validate_password), '%P')) 69 self.utk_e_password.place(x = 150,y = 175) 70 self.utk_e_password.bind("<Return>", self.clear_entry) 71 #创建一个登录按钮 72 self.utk_b_login = Button(root,text="打印",font=("Arial",12),width=10,height=1) 73 self.utk_b_login.place(x = 150,y = 210) 74 self.utk_b_login["command"] = self.songhua 75 #创建一个提示信息标签 76 self.utk_l_info = Label(root,text="快乐工作,幸福生活!!!",font=("Arial",16)) 77 self.utk_l_info.place(x = 30,y = 250) 78 79 def clear_entry(self, event): 80 event.widget.delete(0, END) 81 82 def songhua(self): 83 """判断登录填写是否符合要求""" 84 self.tnsName = self.PSHDBVariable.get().strip() 85 self.name = self.utk_e_op.get().strip() 86 self.password = self.utk_e_password.get().strip() 87 if self.tnsName=="请选择打印机": 88 messagebox.showwarning("警告", "必须选择打印机!!!") 89 elif len(self.name)==0 and self.name=="": 90 messagebox.showwarning("警告", "请输入开始序号") 91 elif len(self.name)!=8: 92 messagebox.showwarning("警告", "开始序号必须8位数") 93 elif self.name.startswith('0'): 94 messagebox.showwarning("警告", "输入的数不能以0开头") 95 elif len(self.password)==0 and self.password=="": 96 messagebox.showwarning("警告", "请输入打印数量") 97 elif int(self.password) > 1000: 98 messagebox.showwarning("警告", "打印数量必须在1~1000") 99 elif int(self.password) < 0: 100 messagebox.showwarning("警告", "打印数量必须在1~1000") 101 else: 102 messagebox.showinfo("打印信息", "恭喜你,输入格式正确,"+self.tnsName+",开始序号:"+self.name+",打印数量是:"+self.password) 103 # self.linkOrcale(self.name,self.password,self.tnsName) 104 a = int(self.name) 105 b = '' 106 d = [] 107 try: 108 selected_printer = win32print.OpenPrinter(self.tnsName) # 获取选择的打印机句柄 109 win32print.StartDocPrinter(selected_printer, 1, ("Print Job", None, None)) # 开始打印任务 110 file = open('data.txt', 'w') 111 for i in range(int(self.password)): 112 a +=1 113 c = str(a) 114 win32print.StartPagePrinter(selected_printer) # 开始打印一页 115 b = '^XA^FO158,170^A@N,35,33,MYRIAD_SET_BOLD_.FNT^FDRM0' + c + '^FS ^FO185,35^BXN,8,400,,,^FDRM0' + c + '^FS^PQ1^XZ' 116 win32print.WritePrinter(selected_printer, b.encode('utf-8')) # 发送ZPL代码到打印机 117 win32print.EndPagePrinter(selected_printer) # 结束打印一页 118 time.sleep(1) # 添加1秒的延迟 119 # print(b) 120 d.append(b) 121 file.write(b+'\n') 122 file.close() 123 win32print.EndDocPrinter(selected_printer) # 结束打印任务 124 win32print.ClosePrinter(selected_printer) # 关闭打印机 125 # print(d) 126 print("数据已成功保存到文件 data.txt 中") 127 # self.print_label() 128 except Exception as e: 129 # 处理异常情况 130 messagebox.showwarning("警告", "打印出错了,请联系【XXX】") 131 print("打印发生错误:", str(e)) 132 133 # 打印label 134 def print_label(self): 135 zpl_code = "^XA^FO50,50^A0N,50,50^FDHello, World!^FS^XZ" 136 selected_printer = win32print.OpenPrinter(self.tnsName) # 获取选择的打印机句柄 137 win32print.StartDocPrinter(selected_printer, 1, ("Print Job", None, None)) # 开始打印任务 138 for _ in range(int(self.password)): 139 win32print.StartPagePrinter(selected_printer) # 开始打印一页 140 win32print.WritePrinter(selected_printer, zpl_code.encode('utf-8')) # 发送ZPL代码到打印机 141 win32print.EndPagePrinter(selected_printer) # 结束打印一页 142 time.sleep(1) # 添加1秒的延迟 143 win32print.EndDocPrinter(selected_printer) # 结束打印任务 144 win32print.ClosePrinter(selected_printer) # 关闭打印机 145 146 147 if __name__ == "__main__": 148 root = Tk() 149 root.geometry("550x300+200+300") 150 root.title("Label打印小工具") 151 app = Application(master=root) 152 root.mainloop()
解决方法:
2023/8/3 下午3:52:27
要使用 pywin32-ctypes 打包 Python 应用程序,可以使用常见的打包工具,如 PyInstaller 或 cx_Freeze。这些工具可以将您的Python脚本及其依赖项打包为可执行文件。
以下是使用 PyInstaller 打包 pywin32-ctypes 的步骤:
-
首先,确保您已经安装了 PyInstaller。您可以使用 pip 进行安装:
Copy Codepip install pyinstaller
-
在命令行中,导航到您的 Python 脚本所在的目录。
-
使用以下命令运行 PyInstaller 来打包您的应用程序:
Copy Codepyinstaller --hidden-import pywintypes your_script.py
注意将 "your_script.py" 替换为您实际的脚本文件名。
-
PyInstaller 将创建一个 "dist" 文件夹,并在其中生成打包后的应用程序。您可以在该文件夹中找到可执行文件。
请记住,pywin32-ctypes 依赖于 pywin32,因此您需要确保已经安装并正确配置了 pywin32。
使用 cx_Freeze 打包 pywin32-ctypes 的步骤类似,但具体命令略有不同。您可以参考 cx_Freeze 的文档进行操作。
值得注意的是,打包复杂的 Python 应用程序可能涉及其他的设置和配置,具体取决于您的应用程序的特定需求。因此,建议您阅读 PyInstaller 或 cx_Freeze 的官方文档,了解更多配置选项和最佳实践。
![](https://c.binjie.fun/assets/avatar-ceeb03f6.jpg)
2023/8/3 下午3:54:16
2023/8/3 下午3:54:32
要打包使用 pywin32 的 Python 应用程序,可以使用常见的打包工具,例如 PyInstaller 或 cx_Freeze。以下是使用 PyInstaller 打包 pywin32 的步骤:
-
确保您已经安装了 PyInstaller。您可以使用 pip 进行安装:
Copy Codepip install pyinstaller
-
在命令行中,导航到您的 Python 脚本所在的目录。
-
运行以下命令来使用 PyInstaller 打包您的应用程序:
Copy Codepyinstaller your_script.py
注意将 "your_script.py" 替换为您实际的脚本文件名。
-
PyInstaller 将创建一个 "dist" 文件夹,并在其中生成打包后的应用程序。您可以在该文件夹中找到可执行文件。
请注意,pywin32 需要依赖于 Windows 上的一些系统库和组件。因此,在打包之前,请确保您的开发环境和目标环境都具备适当的依赖项和运行时支持。您可能还需要将 pywin32 相关的 DLL 文件(例如 pythoncomXX.dll 和 pywintypesXX.dll)复制到您的打包后的应用程序目录中,以确保它们可以正确加载。
使用 cx_Freeze 打包 pywin32 的步骤类似,但具体命令略有不同。您可以参考 cx_Freeze 的文档进行操作。
请注意,打包复杂的 Python 应用程序可能涉及其他的设置和配置,具体取决于您的应用程序的特定需求。因此,建议您阅读 PyInstaller 或 cx_Freeze 的官方文档,了解更多配置选项和最佳实践。
![](https://c.binjie.fun/assets/avatar-ceeb03f6.jpg)
2023/8/3 下午3:55:18
2023/8/3 下午3:55:31
当使用 PyInstaller 或 cx_Freeze 进行打包时,可以将 pythoncomXX.dll
和 pywintypesXX.dll
这两个文件与您的 Python 应用程序一起打包。
对于 PyInstaller,您可以将这两个文件放置在与您的 Python 脚本相同的目录中,然后运行以下命令进行打包:
pyinstaller --add-data "pythoncomXX.dll;." --add-data "pywintypesXX.dll;." your_script.py
请将 XX
替换为适用于您的 Python 版本的数字。这会将这两个 DLL 文件复制到生成的可执行文件所在的目录。
对于 cx_Freeze,您可以通过修改 setup.py
文件来指定需要包含在打包中的文件。在 build_exe_options
中添加类似以下的代码:
build_exe_options = {
'include_files': ['path/to/pythoncomXX.dll', 'path/to/pywintypesXX.dll'],
# 其他的配置项...
}
然后,在命令行中运行 python setup.py build
来执行打包操作。
请确保替换 XX
为适用于您的 Python 版本的数字,并将文件路径替换为实际的路径。
这样,这两个 DLL 文件将与您的 Python 应用程序一起打包,并被复制到生成的可执行文件所在的目录中,以便正确加载和使用 pywin32 功能。
![](https://c.binjie.fun/assets/avatar-ceeb03f6.jpg)
2023/8/3 下午4:17:52
2023/8/3 下午4:18:08
对不起,我之前的回答可能造成了困惑。实际上,在打包 pywin32 应用程序时,并没有一个固定的 pythoncomXX.dll
文件路径。这是因为 pythoncomXX.dll
是根据您当前使用的 Python 版本和安装位置进行命名的。
正确的做法是在您的 Python 安装目录下搜索 pythoncom*.dll
,找到与您正在使用的 Python 版本相对应的 pythoncomXX.dll
文件,然后将其复制到您的项目目录中进行打包。
请按照以下步骤操作:
-
在命令行中输入以下命令,找到
pythoncom*.dll
文件:Copy Codedir /s /b pythoncom*.dll
-
找到与您当前使用的 Python 版本相匹配的
pythoncomXX.dll
文件。- 文件名应该类似于
pythoncom37.dll
(以 Python 3.7 为例)。 - 还可以检查文件属性中的详细信息以确认版本匹配。
- 文件名应该类似于
-
将找到的
pythoncomXX.dll
文件复制到您的项目目录中,或者根据需要放置在与您的 Python 脚本相同的目录中。 -
使用 PyInstaller 或 cx_Freeze 的命令行选项,将
pythoncomXX.dll
和pywintypesXX.dll
与您的 Python 脚本一起打包(具体命令参见前面的回答)。
这样,您将能够将正确版本的 pythoncomXX.dll
和 pywintypesXX.dll
文件与您的应用程序一起打包,并在运行时加载所需的 pywin32 功能。
打包代码setup.py:
1 from cx_Freeze import setup, Executable 2 3 # 定义包含所有依赖项的列表 4 build_exe_options = {"packages": [], "excludes": ['pywin32'], 'include_files': ['pythoncom310.dll', 'pywintypes310.dll']} 5 6 # 创建可执行文件 7 exe = Executable( 8 script="printLabel.py", # 指定要打包的脚本文件 9 base="Win32GUI", # 使用GUI界面 10 ) 11 12 setup( 13 name="PrintLabel", # 项目名称 14 version="1.0", # 版本号 15 description="Label打印小工具", # 描述信息 16 options={"build_exe": build_exe_options}, 17 executables=[exe], 18 )
控制台打包指令:python setup.py build
F:\资料整合\编程资料\编程项目\自己编写的小程序\PYTHON\pythonPrintLabel>python setup.py build