在滚动窗口内绘制区域失败

2024-05-19 05:52:18 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图在PyGTK中通过在滚动窗口中的绘图区域绘制打开的图像来制作图像查看器。由于某些原因,图像没有绘制。以下是查看器的代码:

#!/usr/bin/env python

import gtk
import math
import time

class ImageViewerGTK:
    def __init__(self):

        self.filename = ""

        #Set the Glade file
        self.gladefile = "issue.glade"  
        self.builder = gtk.Builder();
        self.builder.add_from_file(self.gladefile)
        self.window = self.builder.get_object("window")
        self.image = self.builder.get_object("image")
        self.image.set_events(gtk.gdk.POINTER_MOTION_MASK)
        self.builder.connect_signals(self)
        self.builder.get_object("window").show_all()

        self.zoom_slider = self.builder.get_object("zoomlevel")
        self.constrast_slider = self.builder.get_object("contrastlevel")

        self.style = self.image.get_style()
        self.gc = self.style.fg_gc[gtk.STATE_NORMAL]
        self.thumnail_pixmap = gtk.gdk.Pixmap(self.window.get_window(), 25, 25)
        self.mouse_pressed = False

        self.scroll_window = self.builder.get_object("scrolledwindow1")
        self.scroll_vertical = self.scroll_window.get_vadjustment()
        self.scroll_horizontal = self.scroll_window.get_hadjustment()

        self.statusbar = self.builder.get_object("statusbar")

        self.clickX = 0
        self.clickY = 0

    def on_window_destroy(self, widget, data=None):
        gtk.main_quit();

    def on_open_image_activate(self, menuItem, data=None):
        filename = self.get_open_filename()
        if filename: self.load_file(filename)

    def get_open_filename(self):

        filename = None
        chooser = gtk.FileChooserDialog("Open File...", self.window,
                gtk.FILE_CHOOSER_ACTION_OPEN,
                (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, 
                    gtk.STOCK_OPEN, gtk.RESPONSE_OK))

        response = chooser.run()
        if response == gtk.RESPONSE_OK: filename = chooser.get_filename()
        chooser.destroy()

        return filename 

    def load_file(self, filename):
        self.filename = filename
        self.clickX = 0
        self.clickY = 0
        self.pixbuf = gtk.gdk.pixbuf_new_from_file(self.filename)
        pixmap, mask = self.pixbuf.render_pixmap_and_mask()
        self.image.set_size_request(self.pixbuf.get_width(), self.pixbuf.get_height())
        self.image.window.draw_drawable(self.gc, pixmap, 0, 0, 0, 0, -1, -1)

    def image_motion_notify_event_cb(self, widget, event):
       if self.filename != "":
           pixel = self.pixbuf.get_pixels_array()[event.y][event.x]
           self.statusbar.pop(3)
           message = "Gray level: " + str(self.gray_level(pixel[0], pixel[1], pixel[2])) + " @ " + str(event.x) + ", " + str(event.y)
           self.statusbar.push(3, message)

    def gray_level(self, r, g, b):
        return int(0.2126 * r + 0.7152 * g + 0.0722 * b)

if __name__ == "__main__":
   try:
       hwg= ImageViewerGTK()
       gtk.main()
   except KeyboardInterrupt:
       pass

以及角斗篷:

^{pr2}$

如果set U size U请求行被删除,则图像将正确绘制,因此更改绘图区域大小的操作将使其无法绘制任何内容。为什么会这样?在


Tags: 图像imageselfeventgtkgetobjectdef
1条回答
网友
1楼 · 发布于 2024-05-19 05:52:18

您使用GtkDrawingArea不正确。绘图区域不是您只能在其上绘制一次并期望系统刷新绘图的画布;它是一个允许(并要求)您在expose事件期间在其上绘制的小部件。当您需要处理图像时,例如通过将其缩放到该区域,这非常有用。如果您只需要一个小部件来显示现有图像,请使用gtk.Image。在

要正确使用DrawingArea,必须从中派生子类并处理公开事件。例如:

import gtk, gobject

class ImageArea(gtk.DrawingArea):
    __gsignals__ = {'expose-event': 'override'}

    def __init__(self, pixbuf):
        super(ImageArea, self).__init__()
        self._pixbuf = pixbuf

    def do_expose_event(self, event):
        # clip to exposed area
        cr = self.window.cairo_create()
        cr.rectangle(tuple(event.area))
        cr.clip()
        _, _, w, h = tuple(self.allocation)

        # paint over the drawing context:
        pb = self._pixbuf
        cr.set_source_pixbuf(pb, (w - pb.get_width()) / 2, (h - pb.get_height()) / 2)
        cr.paint()

gobject.type_register(ImageArea)

相关问题 更多 >

    热门问题