pum*_*azi 6 python gtk pygtk screenshot
出于测试和文档目的,我想创建一个gtk.Window对象的屏幕截图.我正在关注一个基本的pygtk样本.我修改的示例如下所示:
import gtk
def main():
button = gtk.Button("Hello")
scroll_win = gtk.ScrolledWindow()
scroll_win.add(button)
win = gtk.Window(gtk.WINDOW_TOPLEVEL)
win.add(scroll_win)
win.show_all()
if win.is_drawable() is not True:
raise RuntimeError("Not drawable?")
width, height = win.get_size()
pixbuf = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, False, 8,
width, height)
screenshot = pixbuf.get_from_drawable(win, win.get_colormap(),
0, 0, 0, 0, width, height)
screenshot.save('screenshot.png', 'png')
if __name__ == '__main__':
main()
gtk.main()
Run Code Online (Sandbox Code Playgroud)
调用get_from_drawable方法时,我最终会出错.
TypeError: Gdk.Pixbuf.get_from_drawable() argument 1 must be gtk.gdk.Drawable, not gtk.Window
Run Code Online (Sandbox Code Playgroud)
显然,我合并到基本示例中的屏幕截图示例是使用从gtk.gdk.Drawable继承的gtk.gdk.Window.
我的问题:
voi*_*hos 11
要理解的关键区别在于gtk.gdk.Window,大多数人都不会想到这个"窗口".它不是GUI元素,它只是屏幕的一部分,充当逻辑显示区域,如文档中所述.这样,它更像是一个低级别的对象.
甲gtk.Window对象(传统的"窗口")包含一个window属性,它是gtk.gdk.Window所使用的对象gtk.Window.它在窗口初始化时创建(在这种情况下,在调用之后win.show_all()).
以下是正确保存图像的代码修订版:
import gtk
import gobject
def main():
button = gtk.Button("Hello")
scroll_win = gtk.ScrolledWindow()
scroll_win.add(button)
win = gtk.Window(gtk.WINDOW_TOPLEVEL)
win.add(scroll_win)
win.show_all()
# Set timeout to allow time for the screen to be drawn
# before saving the window image
gobject.timeout_add(1000, drawWindow, win)
def drawWindow(win):
width, height = win.get_size()
pixbuf = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, False, 8, width, height)
# Retrieve the pixel data from the gdk.window attribute (win.window)
# of the gtk.window object
screenshot = pixbuf.get_from_drawable(win.window, win.get_colormap(),
0, 0, 0, 0, width, height)
screenshot.save('screenshot.png', 'png')
# Return False to stop the repeating interval
return False
if __name__ == '__main__':
main()
gtk.main()
Run Code Online (Sandbox Code Playgroud)
超时是必要的,因为即使gtk.gdk.Window创建了对象,屏幕仍然没有被绘制,直到gtk.main()开始运行,我想.如果您刚刚读取像素缓冲区win.show_all(),它将保存图像,但图像将是窗口稍后将占用的屏幕部分.如果您想亲自尝试,请将呼叫替换gobject.timeout_add为简单的呼叫drawWindow(win).
请注意,此方法保存GTK窗口的图像,但不保存窗口的边框(因此,没有标题栏).
另外,作为一个侧点,当定义一个被调用的函数时,gobject.timeout_add实际上你不必return False显式地使用它,它只需要计算一个等价的值0.None如果return函数中没有语句,Python 默认返回,因此该函数默认只调用一次.如果希望在另一个间隔后再次调用该函数,则返回True.
正如liberforce所指出的,更好的方法是连接到GTK用来传递事件(以及一般状态变化)的信号,而不是使用超时.
任何继承的东西gobject.GObject(基本上所有小部件都有)具有一个connect()用于向给定信号注册回调的函数.我尝试了一些信号,看起来我们想要使用的是expose-event,任何时候需要重绘一个小部件(包括第一次绘制它)时都会发生这种信号.因为我们希望在回调发生之前绘制窗口,所以我们将使用connect_after()变体.
这是修改后的代码:
import gtk
# Don't use globals in a real application,
# better to encapsulate everything in a class
handlerId = 0
def main():
button = gtk.Button("Hello")
scroll_win = gtk.ScrolledWindow()
scroll_win.add(button)
win = gtk.Window(gtk.WINDOW_TOPLEVEL)
win.add(scroll_win)
# Connect to expose signal to allow time
# for the window to be drawn
global handlerId
handlerId = win.connect_after('expose-event', drawWindow)
win.show_all()
def drawWindow(win, e):
width, height = win.get_size()
pixbuf = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, False, 8, width, height)
# Retrieve the pixel data from the gdk.window attribute (win.window)
# of the gtk.window object
screenshot = pixbuf.get_from_drawable(win.window, win.get_colormap(),
0, 0, 0, 0, width, height)
screenshot.save('screenshot.png', 'png')
# Disconnect this handler so that it isn't
# repeated when the screen needs to be redrawn again
global handlerId
win.disconnect(handlerId)
if __name__ == '__main__':
main()
gtk.main()
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3914 次 |
| 最近记录: |