Python 3.x 如何将整个tkinter画布截屏为png或pdf

Python 3.x 如何将整个tkinter画布截屏为png或pdf,python-3.x,canvas,tkinter,save,runtime-error,Python 3.x,Canvas,Tkinter,Save,Runtime Error,我正在创建一个程序,该程序设计为。。。它的设计目的是让D&D更容易塑造角色。(我是一名DM,我花了很多时间把表格放在一起,而这应该是一个简单的过程。当我知道我想要什么时,这段代码最终将成为一个大规模程序的一部分,该程序将把过程从数小时简化到数分钟。对我来说,这是值得的。)所有角色创建部分都在一个单独的代码中,但我一直在努力的是能够打开一个字符表,把所有问题的答案都放进去,并保存输出供以后打印。 请注意,我在python3上使用windows 8,并实际安装了所有模块pip是的 我想: 打开png

我正在创建一个程序,该程序设计为。。。它的设计目的是让D&D更容易塑造角色。(我是一名DM,我花了很多时间把表格放在一起,而这应该是一个简单的过程。当我知道我想要什么时,这段代码最终将成为一个大规模程序的一部分,该程序将把过程从数小时简化到数分钟。对我来说,这是值得的。)所有角色创建部分都在一个单独的代码中,但我一直在努力的是能够打开一个字符表,把所有问题的答案都放进去,并保存输出供以后打印。 请注意,我在python3上使用windows 8,并实际安装了所有模块pip是的

我想:

  • 打开png图像(或PDF)

  • 在上面写上新信息

  • 将输出另存为新文件

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

    我现在可以做的是:

  • 打开一个PNG(但不是原始的PDF。我必须首先转换它,因为很多原因我不会在这里讨论。)

  • 在图像的画布窗口中显示我想要的信息

  • 不幸的是,我似乎无法保存整个画布。到目前为止,我得到的最接近的是一张截图,它实际上截屏了我的整个电脑显示器。因此,我的画布(上角)只有大约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()
    
    从tkinter导入*
    将tkinter.ttk导入为ttk
    将PIL.Image作为图像导入
    将PIL.ImageTk导入为ImageTk
    将PIL.ImageGrab导入为ImageGrab
    导入操作系统
    #我单独导入了所有这些PIL部分,因为导入了整个
    #一件事,或者一条线上的所有东西,在调用中导致了如此多的错误
    #功能。由于某种原因,我的电脑讨厌功能,我从来没有太多功能
    #成功与他们同在。因此,试图创建没有它们的程序。
    def on_垂直(事件):
    canvas.yview\u滚动(-1*event.delta,“单位”)
    def位于水平位置(事件):
    canvas.xview_滚动(-1*event.delta,“单位”)
    root=Tk()
    root.title('您在此处的角色')
    h=滚动条(根,方向=水平)
    v=滚动条(根,方向=垂直)
    画布=画布(根,滚动区域=(0,012754960),
    yscrollcommand=v.set,
    xscrollcommand=h.set)
    h['command']=canvas.xview
    v['command']=canvas.yview
    输出=ImageTk.PhotoImage(Image.open('charpg4.png'))
    canvas.create_image(0,0,image=output,anchor='nw')
    网格(列=0,行=0,粘性=(N,W,E,S))
    画布。全部绑定(“”,垂直)
    画布。全部绑定(“”,水平)
    h、 网格(列=0,行=1,粘性=(W,E))
    v、 网格(列=1,行=0,粘性=(N,S))
    root.grid\u columnconfigure(0,权重=1)
    root.grid_rowconfigure(0,权重=1)
    测试=(“一”、“二”、“三”、“测试”)
    画布。创建_文本(210155,fill='black',font='Helvetica 10',
    文本=测试)
    canvas.update()
    grabcanvas=ImageGrab.grab(bbox=canvas.save)(“test.png”)
    ttk.grabcanvas.save(“test.png”)
    #下面的代码可以工作,但显然只需要一个直接的屏幕截图
    #ImageGrab.grab().save(“test.jpg”)
    #--其他人都试过了,但对我不起作用??
    #导致bbox和ImageGrab出错
    #self.grabcanvas=ImageGrab.grab(bbox=canvas)
    #导致保存错误,表示没有此类选项
    #grab(bbox=canvas).save(“test.jpg”)
    #冻结和崩溃的游戏,没有做任何事情在最后。
    #postscript(file='test.ps',size=(12754960),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
    
    回溯(最近一次呼叫最后一次):
    文件“C:/Users/秋/Documents/programs/tests/dnd game/saving
    输出/窗口大小3.py”,第42行,输入
    grabcanvas=ImageGrab.grab(bbox=canvas.save)(“test.png”)
    文件“C:\ProgramFiles(x86)\Python36-32\lib\site-
    packages\PIL\ImageGrab.py“,
    第48行,在抓斗中
    im=im.作物(bbox)
    文件“C:\ProgramFiles(x86)\Python36-32\lib\site-
    packages\PIL\Image.py“,
    第1078行,在作物中
    返回self.\u新建(self.\u裁剪(self.im,box))
    文件“C:\ProgramFiles(x86)\Python36-32\lib\site-
    packages\PIL\Image.py“,
    第1092行,in_作物
    x0,y0,x1,y1=映射(整数,映射(圆形,方框))
    文件“C:\ProgramFiles(x86)\Python36-32\lib\tkinter\\uuuu init\uuuu.py”,
    第1486行,在cget中
    返回self.tk.call(self._w,'cget','-'+键)
    TypeError:必须是str,而不是int
    
    通常我会找出我的代码有什么问题,但我不能,基于我在网上找到的所有东西,Image.Save或ImageGrab.Save或Image.write。。。这些应该在tk中起作用。。。
    它似乎是指tkinter中不调用“cget”或某种字符串的函数。。因为我从来没有在它所指的行中放入整数,也从来没有像错误所指的那样进行裁剪。

    您遇到的问题是如何将
    canvas
    传递到
    bbox
    grab()
    需要一组坐标,而不是像canvas这样的对象

    请尝试以下方法:

    在调用
    update()
    后删除此项:

    grabcanvas=ImageGrab.grab(bbox=canvas).save("test.png")
    ttk.grabcanvas.save("test.png")
    
    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)
    
    然后在调用
    update()
    后添加此项:

    grabcanvas=ImageGrab.grab(bbox=canvas).save("test.png")
    ttk.grabcanvas.save("test.png")
    
    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)
    

    您的问题似乎在这里
    grabcanvas=ImageGrab.grab(bbox=canvas.save)(“test.png”)
    。画布不是一组坐标。是的,这是我不断改变的路线,尝试不同的东西