如何创建和打开一个集成了 tkinter 和 Reportlabs 包的 pdf?

How to create and open a pdf integrating tkinter and Reportlabs packages?

对于我们的研究项目,我和我的队友使用存储在名为“PDFCanvas”的 Python 文件中的 Reportlabs 包创建了一个 pdf 文件生成器代码。在另一个名为“AppTest”的 Python 文件中,它包含我们的带按钮的 tkinter GUI,我们复制粘贴了我们的 PDFCanvas 文件代码,以尝试使用该按钮初始化 PDF 的创建和查看,这当然可以在单独的文件中使用文件。显然,当我们运行“AppTest”中的程序时,它提示我们错误:AttributeError: 'str' object has no attribute 'tk'。我们能否就如何获得它寻求帮助?运行ning?

删除单独的 PDF 创建者的第一个参考工作代码是我的错误,但它是:

from reportlab.pdfgen.canvas import Canvas
from reportlab.lib.pagesizes import LETTER
from reportlab.lib.units import inch, cm
from reportlab.pdfgen.canvas import *
from reportlab.lib.colors import *
from reportlab.rl_config import defaultPageSize
from reportlab.pdfbase.pdfmetrics import stringWidth

page_height = defaultPageSize[1]
page_width = defaultPageSize[0]

import os
import sys
import subprocess
import sqlite3

canvas = Canvas("Report - Name [Date].pdf")
canvas.setFont("Helvetica-Bold", 14)
canvas.drawString(72, 795.68, "Veterinary Office")
canvas.save()
subprocess.Popen(['Report - Name [Date].pdf'], shell=True)

更新 - 这是生成错误的代码示例:

from reportlab.pdfgen.canvas import Canvas
from reportlab.lib.pagesizes import LETTER
from reportlab.lib.units import inch, cm
from reportlab.pdfgen.canvas import *
from reportlab.lib.colors import *
from reportlab.rl_config import defaultPageSize
from reportlab.pdfbase.pdfmetrics import stringWidth

page_height = defaultPageSize[1]
page_width = defaultPageSize[0]

import os
import sys
import sqlite3
import subprocess
import tkinter as tk
import tkinter.ttk as ttk
import tkinter.font as tkFont
from tkinter import *

run = tk.Tk()

def PDFPrint():
    canvas = Canvas("Report - Name [Date].pdf")
    canvas.setFont("Helvetica-Bold", 14)
    canvas.drawString(72, 795.68, "Vet Office")

    canvas.save()
    subprocess.Popen(['Report - Name [Date].pdf'], shell=True)

aButton = Button(run, text = 'Print', command = PDFPrint())

run.mainloop()

对于完整的错误堆栈:

Traceback (most recent call last):
  File "C:\Users\Desktop\AppTest.py", line 32, in <module>
    aButton = Button(run, text = 'Print', command = PDFPrint())
  File "C:\Users\Desktop\AppTest.py", line 25, in PDFPrint
    canvas = Canvas("Report - Name [Date].pdf")
  File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.9_3.9.752.0_x64__qbz5n2kfra8p0\lib\tkinter\__init__.py", line 2688, in __init__
    Widget.__init__(self, master, 'canvas', cnf, kw)
  File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.9_3.9.752.0_x64__qbz5n2kfra8p0\lib\tkinter\__init__.py", line 2566, in __init__
    BaseWidget._setup(self, master, cnf)
  File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.9_3.9.752.0_x64__qbz5n2kfra8p0\lib\tkinter\__init__.py", line 2535, in _setup
    self.tk = master.tk
AttributeError: 'str' object has no attribute 'tk'
[Finished in 1.3s]

我们已经通过 pip 预安装了 ReportLabs 库。我希望我提供了足够的信息,以便可以为我们的这个问题提供答案。谢谢!

我明白了。导入时您使用了:

from reportlab.pdfgen.canvas import Canvas
...
from tkinter import *

但问题是 tkinter 还定义并覆盖了从 reportlab 导入的 Canvas。这就是为什么你应该避免 import *。要解决该问题,只需将其更改为 import tkinter as tk,然后在您使用 tkinter widgets/variables 的任何地方添加 tk.tkinter.Canvas 需要一个 tkinter 小部件作为第一个参数,这与 reportlab.pdfgen.canvas.Canvas 需要一个字符串不同。

也将此:aButton = Button(run, text = 'Print', command = PDFPrint()) 更改为:

aButton = Button(run, text = 'Print', command = PDFPrint)

TL;DR 您导入了 Canvas 两次,其中一个定义丢失了(您想要使用的定义)。