Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 3.x Python-如何与打印机通信_Python 3.x_Printing_Pywin32_Pycups - Fatal编程技术网

Python 3.x Python-如何与打印机通信

Python 3.x Python-如何与打印机通信,python-3.x,printing,pywin32,pycups,Python 3.x,Printing,Pywin32,Pycups,几天来,我一直在寻找如何改进我为工作编写的程序。该程序使用Python3.6,只是将预格式化的.doc文件发送到打印机,但我似乎找不到一种方法来通知函数在打印机用完纸张后停止发送文件进行打印。打印的文档数量不同,因此我不能只使用简单的范围函数 我已经研究了win32print模块和pycups模块(无论我怎么尝试,它们都不会进行pip安装)。信号模块中是否存在从其他应用程序捕获外部错误消息的功能?理想情况下,最好是python脚本能够在发送文件之前首先检查打印队列的状态 我发现下面的代码,使用w

几天来,我一直在寻找如何改进我为工作编写的程序。该程序使用Python3.6,只是将预格式化的.doc文件发送到打印机,但我似乎找不到一种方法来通知函数在打印机用完纸张后停止发送文件进行打印。打印的文档数量不同,因此我不能只使用简单的范围函数

我已经研究了win32print模块和pycups模块(无论我怎么尝试,它们都不会进行pip安装)。信号模块中是否存在从其他应用程序捕获外部错误消息的功能?理想情况下,最好是python脚本能够在发送文件之前首先检查打印队列的状态

我发现下面的代码,使用win32print模块,应该可以实现这一点,但它似乎不起作用

import win32print

p = win32print.OpenPrinter("Canon Inkjet iP1800 series")

raw = win32print.EnumJobs(p, 0, 999)

def main():
    while len(raw) > 0:
        #does some function

    if #receives error from printer:
        break

main()

win32print.ClosePrinter(p)

旁注:我必须说pywin32是基于Win的,而pycups(或任何cups包装器)是基于Ux的,因此,除非我不知道有一些用于Win的cups端口,否则您应该选择上面2个中的一个(最好与您所在的平台/拱门匹配)

我做了一些研究,没有必要重复所有的打印机作业,以检查打印机是否处于错误状态。此外,将作业从0循环到999并不能保证检查所有作业,因此上述逻辑(即使它是正确的,但事实并非如此)不成立

下面是一个示例实现(我随意添加了比问题中指定的更多的错误:纸张用完(
win32print.PRINTER\u STATUS\u paper\u out
)并将它们放入
PRINTER\u ERROR\u STATES
(注释掉您不认为是错误的部分):


注意:很明显,Win没有将打印机名称存储为打印机上设置的名称。在我的例子中,我有一台名为EPSON******的打印机。但是在Win中,它的名称是EPSON****(WF-7610系列)。这就是为什么我必须编写一些附加代码(我在这里没有包括这些代码)列举所有可用的打印机并获取它们的名称。

旁注:我必须说pywin32是基于Win的,而pycups(或任何cups包装器)是基于Ux的,因此,除非我不知道Win有一些cups端口,否则您应该从上述2个端口中选择一个(最好是匹配您所在的平台/拱门)

我做了一些研究,没有必要为了检查打印机是否处于错误状态而反复检查所有的打印机作业。此外,将作业从0循环到999并不能保证检查了所有的作业,因此上面的逻辑(即使它是正确的,但事实并非如此)不成立

下面是一个示例实现(我随意添加了比问题中指定的更多的错误:纸张用完(
win32print.PRINTER\u STATUS\u paper\u out
)并将它们放入
PRINTER\u ERROR\u STATES
(注释掉您不认为是错误的部分):

注意:很明显,Win没有将打印机名称存储在打印机上。在我的例子中,我有一台名为EPSON******的打印机。但是在Win中,它的名称是EPSON*******(WF-7610系列)。这就是为什么我必须编写一些额外的代码(我在这里没有包含)来枚举所有可用的打印机并获取它们的名称

import win32print

PRINTER_ERROR_STATES = (
    win32print.PRINTER_STATUS_NO_TONER,
    win32print.PRINTER_STATUS_NOT_AVAILABLE,
    win32print.PRINTER_STATUS_OFFLINE,
    win32print.PRINTER_STATUS_OUT_OF_MEMORY,
    win32print.PRINTER_STATUS_OUTPUT_BIN_FULL,
    win32print.PRINTER_STATUS_PAGE_PUNT,
    win32print.PRINTER_STATUS_PAPER_JAM,
    win32print.PRINTER_STATUS_PAPER_OUT,
    win32print.PRINTER_STATUS_PAPER_PROBLEM,
)


def printer_errorneous_state(printer, error_states=PRINTER_ERROR_STATES):
    prn_opts = win32print.GetPrinter(printer)
    status_opts = prn_opts[18]
    for error_state in error_states:
        if status_opts & error_state:
            return error_state
    return 0


def main():
    printer_name = "Canon Inkjet iP1800 series" # or get_printer_names()[0]
    prn = win32print.OpenPrinter(printer_name)
    error = printer_errorneous_state(prn)
    if error:
        print("ERROR occurred: ", error)
    else:
        print("Printer OK...")
        #  Do the real work

    win32print.ClosePrinter(prn)


if __name__ == "__main__":
    main()