首页 > 解决方案 > 如何创建和打开集成 tkinter 和 Reportlabs 包的 pdf?

问题描述

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

我不喜欢删除单独的 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 库。我希望我提供了足够的信息,以便可以为我们的这个问题提供答案。谢谢!

标签: pythonpdftkintercanvasreportlab

解决方案


我想到了。导入时使用:

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

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

也改变这个:aButton = Button(run, text = 'Print', command = PDFPrint())到这个:

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

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


推荐阅读