python-3.x - 如何将整个 tkinter 画布截图为 png 或 pdf
问题描述
我正在创建一个经过设计的程序......它旨在让 D&D 老实说,角色构建更容易。(我是一名 DM,当我知道自己想要什么的时候,我花了很长时间把表格放在一起,这应该是一个简单的过程,这段代码最终将成为一个大型程序的一部分,将过程从几小时简化到几分钟。对我来说,非常值得。)所有的角色创建部分都在一个单独的代码中,但我一直在做的是能够打开一个角色表,把所有问题的答案都放进去,然后保存输出以备后用印刷。请注意我在 python3 上,使用 Windows 8,并且我的所有模块实际上都安装了 pip 是的。
我想要 :
打开 png 图像(或 PDF)
在上面写入新信息
将输出另存为新文件。
< 请注意,我根本不想在其中使用类或函数。我想要所有简单的东西。>
我已经可以做的:
打开一个 PNG(但不是原始的 PDF。我必须先转换它,原因有很多,我不会在这里介绍。)
在图像的画布窗口中显示我想要的信息。
不幸的是,我似乎无法保存整个画布。到目前为止,我得到的最接近的是 ImageGrab,它实际上截取了我的整个计算机显示器。因此,我的画布(顶角)只有大约 500*250 像素。
我需要弄清楚我在这里做错了什么。我将一些代码离线以使滚动条正常工作,我根本不认为这是我自己的。将输出保存为我可以查看的任何内容时遇到问题。我得到了一个附言文件,当我把它放回一个可视图像时,仍然只是整个画布的一部分快照。我需要一些东西来显示你需要滚动的部分。
当前代码在 Tkinter 包中以某种方式引发了异常,在其他情况下,我在网上只发现了大约 27 次,没有一个答案实际上适用于我的错误。我看了又看,非常感谢有关如何解决这个问题的帮助。
from tkinter import *
import tkinter.ttk as ttk
import PIL.Image as Image
import PIL.ImageTk as ImageTk
import PIL.ImageGrab as ImageGrab
import os
#I imported all these PIL sections seperate because importing the whole
#thing as one, or alltogether on one line caused so many errors in calling
#the functions. my pc for some reason HATES functions, ive NEVER had much
#success with them. hence trying to create programs without them.
def on_vertical(event):
canvas.yview_scroll(-1 * event.delta, 'units')
def on_horizontal(event):
canvas.xview_scroll(-1 * event.delta, 'units')
root = Tk()
root.title('Your Character Here')
h = Scrollbar(root, orient=HORIZONTAL)
v = Scrollbar(root, orient=VERTICAL)
canvas = Canvas(root, scrollregion=(0, 0, 1275, 4960),
yscrollcommand=v.set,
xscrollcommand=h.set)
h['command'] = canvas.xview
v['command'] = canvas.yview
output = ImageTk.PhotoImage(Image.open('charpg4.png'))
canvas.create_image(0,0,image=output, anchor='nw')
canvas.grid(column=0, row=0, sticky=(N,W,E,S))
canvas.bind_all('<MouseWheel>', on_vertical)
canvas.bind_all('<Shift-MouseWheel>', on_horizontal)
h.grid(column=0, row=1, sticky=(W,E))
v.grid(column=1, row=0, sticky=(N,S))
root.grid_columnconfigure(0, weight=1)
root.grid_rowconfigure(0, weight=1)
testing=("one", "two", "three", "testing")
canvas.create_text(210,155,fill='black',font='Helvetica 10',
text=testing)
canvas.update()
grabcanvas=ImageGrab.grab(bbox=canvas).save("test.png")
ttk.grabcanvas.save("test.png")
#the following code works but apparently takes only a direct screenshot
#ImageGrab.grab().save("test.jpg")
#--these others have been tried but dont work for me??
#causes an error with bbox and ImageGrab
#self.grabcanvas = ImageGrab.grab(bbox=canvas)
#Causes the save error, says no such option
#ImageGrab.grab(bbox=canvas).save("test.jpg")
#froze and crashed the game, didnt do anything in the end.
#canvas.postscript(file='test.ps', size =(1275, 4960), colormode='gray')
root.mainloop()
这是引发的代码错误。
Traceback (most recent call last):
File "C:/Users/Autumn/Documents/programs/tests/dnd game/saving
output/windowsize 3.py", line 42, in <module>
grabcanvas=ImageGrab.grab(bbox=canvas).save("test.png")
File "C:\Program Files (x86)\Python36-32\lib\site-
packages\PIL\ImageGrab.py",
line 48, in grab
im = im.crop(bbox)
File "C:\Program Files (x86)\Python36-32\lib\site-
packages\PIL\Image.py",
line 1078, in crop
return self._new(self._crop(self.im, box))
File "C:\Program Files (x86)\Python36-32\lib\site-
packages\PIL\Image.py",
line 1092, in _crop
x0, y0, x1, y1 = map(int, map(round, box))
File "C:\Program Files (x86)\Python36-32\lib\tkinter\__init__.py",
line 1486, in cget
return self.tk.call(self._w, 'cget', '-' + key)
TypeError: must be str, not int
通常我会找出我的代码有什么问题,但我不能,基于我在网上找到的所有内容,Image.Save 或 ImageGrab.save 或 Image.write ......这些应该在 tk 中工作。...它似乎是指 tkinter 中的一个函数,它不调用'cget'或某种字符串。因为我从来没有在它所指的行中放入一个整数,而且我从来没有裁剪,因为错误是指.
解决方案
您遇到的问题是您传递canvas
给bbox
. grab()
需要获取一组坐标,而不是像画布这样的对象。
试试这个:
通话后删除update()
:
grabcanvas=ImageGrab.grab(bbox=canvas).save("test.png")
ttk.grabcanvas.save("test.png")
然后在update()
调用后添加:
def save_canvas():
x = root.winfo_rootx() + canvas.winfo_x()
y = root.winfo_rooty() + canvas.winfo_y()
xx = x + canvas.winfo_width()
yy = y + canvas.winfo_height()
ImageGrab.grab(bbox=(x, y, xx, yy)).save("test.gif")
root.after(1000, save_canvas)
推荐阅读
- javascript - Command which shows the number of people having a role when the role name is typed in discord.js v12
- sql - 如何将所有文本行值转换为 SQL Server 中的列
- javascript - 无法通过 Google 脚本启用 Slack 的“启用事件”
- google-apps-script - 谷歌表格下拉选择
- javascript - 如何在 laravel 中使用 yajra 数据表删除数据?
- javascript - 给定扁平数组索引,如何在数组树中找到节点的路径?
- prometheus - promql:如何在一段时间内找到丢失的行
- android - 如何从 Azure DevOps 的 Android 版本中获取修订号并将其显示在 Android 应用程序中?
- c# - 无法将 json 对象反序列化为模型类类型
- html - 如何为 HTML 标签设置背景颜色?