如何将整个tkinter画布截图为png或pdf

问题描述 投票:0回答:1

我正在创建一个专门设计的程序......它的目的是让角色建设更容易让D&D老老实实。 (我是一名DM,我花了很多时间将这些纸张放在一起,当我知道我想要的时候它应该是一个简单的过程。这段代码最终将成为一个大规模程序的一部分,简化了从几小时到几分钟的过程。对我来说非常值得。)所有角色创建部分都在一个单独的代码中,但我一直在努力的是能够打开一个角色表,将所有问题的答案放入其中,并保存输出以供日后使用打印。注意我在python3上,使用Windows 8,并让我所有的模块实际上是pip安装是的。

我想要 :

  1. 打开png图像(或PDF)
  2. 在其上写下新信息
  3. 将输出保存为新文件。

<注意,我根本不想在这里使用类或函数。我想要所有简单的事情。>

我能做什么:

  1. 打开一个PNG(但不是原始的PDF。我不得不首先将其转换为SOO很多原因我不会进入这里。)
  2. 在图像的画布窗口中显示我想要的信息。

不幸的是,我似乎无法保存整个画布。我得到的最接近的是ImageGrab到目前为止,它实际上截断了我的整个电脑显示器。因此我的画布(顶角)只有大约500 * 250像素。

我需要弄清楚我在这里做错了什么。我拉了一些代码离线以使我的滚动条工作,我根本不认为这是我自己的。我将输出保存为我可以查看的任何内容时出现问题。我有一个postscript文件,当我把它放回到一个可查看的图像时,结果仍然只是整个画布的部分快照。我需要一些能够显示你需要滚动的部分的东西。

当前代码在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'或某种字符串...因为我从来没有把一个整数放入它引用的行中,而且我从不裁剪,因为错误指的是。

python-3.x canvas tkinter save runtime-error
1个回答
0
投票

你遇到的问题是你将canvas传递给bbox的方式。 grab()需要采取一些coords而不是像canvas这样的对象。

试试这个:

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)
© www.soinside.com 2019 - 2024. All rights reserved.