Tkinter Canvas Postscript 未捕获屏幕框架外的 Window 元素

Posted

技术标签:

【中文标题】Tkinter Canvas Postscript 未捕获屏幕框架外的 Window 元素【英文标题】:Tkinter Canvas Postscript not capturing Window elements outside of screen frame 【发布时间】:2017-04-13 11:28:00 【问题描述】:

正如标题所说,当尝试使用 Postscript 保存 Canvas 时,它适用于所有非窗口元素(矩形、椭圆等),并且它可以完美地捕捉我按下时屏幕上当前显示的窗口元素按钮。但当时没有任何窗口元素出现在屏幕之外。

这个问题似乎太武断了,我想知道是否有解决方案,希望有人已经解决了。

这是一些示例代码,我在其中简化以呈现确切的问题:

#!/usr/bin/python3
#
# This file is intended as a simplified example for Stack Overflow.
# The original program is far greater and is a writing tool for branching dialogue, much like Twine.

from tkinter import Tk, Canvas, Frame, Text, Label

class Canv(Canvas):
    def __init__(self, parent):
        """Simple Canvas class."""
        Canvas.__init__(self, parent)
        self.parent = parent
        self.config(background="white", width=960, height=640)
        self.num = 1
        self.pack()
        self.bindings()

    def bindings(self):
        """All the button bindings."""
        self.bind("<Button-1>", self.add_window)
        self.bind("<ButtonPress-2>", self.mark)
        self.bind("<ButtonRelease-2>", self.drag)
        self.bind("<Button-3>", self.take_ps)

    def add_window(self, e):
        """Here I add the Label as a Canvas window.
           And include an Oval to mark its location.
        """
        text = "Textwindow ".format(self.num)
        self.num += 1
        window = TextWindow(self, text)
        pos = (self.canvasx(e.x), self.canvasy(e.y))
        self.create_window(pos, window=window)
        bbox = (pos[0]-50, pos[1]-50, pos[0]+50, pos[1]+50)
        self.create_oval(bbox, width=3, outline="green")

    def mark(self, e):
        """Simple Mark to drag method."""
        self.scan_mark(e.x, e.y)

    def drag(self, e):
        """This drags, using the middle mouse button, the canvas to move around."""
        self.scan_dragto(e.x, e.y, 5)

    def take_ps(self, e):
        """Here I take a .ps file of the Canvas.
           Bear in mind the Canvas is virtually infinite, so I need to set the size of the .ps file
           to the bounding box of every current element on the Canvas.
        """
        x1, y1, x2, y2 = self.bbox("all")
        self.postscript(file="outfile.ps", colormode="color", x=x1, y=y1, width=x2, height=y2)
        print("Writing file outfile.ps...")

class TextWindow(Frame):
    def __init__(self, parent, text):
        """Very simple label class.
           Might have been overkill, I originally intended there to be more to this class,
            but it proved unnecesary for this example.
        """
        Frame.__init__(self, parent)
        self.pack()
        self.label = Label(self, text=text)
        self.label.pack()



if __name__ == "__main__":   #<---Boilerplate code to run tkinter.
    root = Tk()
    app = Canv(root)
    root.mainloop()

This is an example .jpg based on the postscript.

从图片中可以看出,右侧所有绿色圆圈的窗口标签都完好无损。好吧,所有的绿色圆圈都应该有它们,并且在程序中它们运行良好,只是没有在后记中显示。是的,当我点击 take_ps 按钮时,我的屏幕在右侧圆圈上方。

至于替代方案,我需要画布是可拖动的,我需要它扩展,可能在两个方向上都有很大的距离。而且我不能将文本直接放在画布上,因为它会占用太多空间。它的目的是在画布上的窗口中包含文本字段,而不仅仅是一个标签(对于这个例子来说代码太多了),我需要在窗口中而不是直接在屏幕上的原因是文本可能很容易占用更多空间。我需要画布来显示文本字段之间的关系,而文本窗口则需要包含用于编辑的文本,不一定要完全显示。正如它所说,我正在为游戏制作一个分支对话工具,就像 Twine 一样。

【问题讨论】:

如果你仍然迫切需要解决这个问题,我明天可以给你一个 100 代表的赏金。 那真是太酷了。这是最有可能是相关 C 代码的链接:tcl github 那里有一些 NULL 语句可能是问题所在,但我不会说 C。:-/ 至于 tk_state_hidden,这不是问题,因为它很容易测试。 似乎没有帮助,对不起,伙计。您可能想改写问题并重新发布。你可以把标题改得更简单,我从没想过我会这么说,clickbaitier one。还要改进图片:而不是链接后面的图片,将它们包含在帖子本身中。 “我拥有什么”与“我想要什么”的图像通常有助于为这个问题赢得人气。您可能会稍微缩短问题的主体,使其简短而简洁。去掉更多的代码,将其缩小到尽可能少。 补充:对于 *** 问题,您不需要代码是“完美的”,您希望它尽可能简短和干净,同时仍然能够产生您的问题。例如,去掉所有的文档字符串、cmets、if __name__ == '__main__':、额外的打印和特性,一切。 【参考方案1】:

我也遇到了这个问题。我能够临时配置画布以匹配输出图像的大小。然后我在完成创建 postscript 文件后将其配置回原始大小。

height_0 = canvas.winfo_height()
width_0 = canvas.winfo_width()
canvas.config(width= max_width, height= max_height)
root.update()
canvas.postscript(file='filename.ps',colormode='color')
canvas.config(width= width_0, height= height_0)
root.update()

【讨论】:

以上是关于Tkinter Canvas Postscript 未捕获屏幕框架外的 Window 元素的主要内容,如果未能解决你的问题,请参考以下文章

Python tkinter 将画布保存为 postscript 并添加到 pdf

Python Tkinter - 保存画布 - tkinter 崩溃

Python3 tkinter,怎么在Label/Canvas中插入图片?

如何在 Canvas 上的 Tkinter 中打开 PIL 图像

同时移动多个 tkinter.canvas 图形

Python tkinter canvas实现图片裁剪