Gtk scrolledwindow:滚动到顶部需要奇怪的延迟

时间:2018-01-14 19:23:31

标签: python python-3.x gtk gtk3

编辑:在python 3.6,linux,gtk 3.22上运行

我写了一个简单的应用程序,它在一个文件夹中显示图像,并允许使用箭头键(通常是一个简单的漫画查看器;通过高度>宽度的图像尝试它)来浏览它们。每个图像都放大了,因此要查看其底部,您需要向下滚动。当您加载下一个图像时,应用程序应将滚动条还原到上半部分。我的当前代码只有在我按下右箭头键查看下一个图像之前等待几秒钟(即滚动条消失所需的时间)才能正确执行此操作,否则它会将下一个图像加载到底部。我不明白为什么。

编辑:请注意,只有在使用触摸板滚动时才会出现错误,而不是在拖动滚动条时。

#!/usr/bin/python3
import sys
import os
from gi import require_version
require_version('Gtk', '3.0')
from gi.repository import Gtk, Gdk, GdkPixbuf

class Comic:
    def __init__(self, filelist):
        self.files = filelist
        self.index = 0

        self.zoom = 0.50

        self.window = Gtk.Window()
        self.window.props.can_focus = False
        self.window.props.default_width = 1366
        self.window.props.default_height = 768
        self.window.props.startup_id = 'app.comic'
        self.window.props.title = 'comic'

        self.window.connect("delete-event", Gtk.main_quit)
        self.window.connect("key-press-event", self._on_key_press)

        self.scrolledwindow = Gtk.ScrolledWindow()
        self.scrolledwindow.props.visible = True
        self.scrolledwindow.props.can_focus = True
        self.scrolledwindow.props.hexpand = True
        self.scrolledwindow.props.vexpand = True
        self.window.add(self.scrolledwindow)

        self.image = Gtk.Image()
        self.scrolledwindow.add(self.image)
        self._open_image()

    def _on_key_press(self, win, ev):
        key = Gdk.keyval_name(ev.keyval)
        if key in ('Left', 'KP_Left'):
            self.previous_image()
        elif key in ('Right', 'KP_Right'):
            self.next_image()
        elif key == 'q':
            Gtk.main_quit()

    def _on_resize(self):
        scrolled_allocation = self.scrolledwindow.get_allocation()

        w = self.image_width
        h = self.image_height

        if h > scrolled_allocation.height:
            scale = scrolled_allocation.height / h
            w *= scale
            h *= scale

        if w > scrolled_allocation.width:
            scale = scrolled_allocation.width / w
            w *= scale
            h *= scale

        w = int(w)
        h = int(h)

        w = w + w * self.zoom
        h = h + h * self.zoom

        if (w != self.image_width or h != self.image_height) and w > 0 and h > 0:
            pixbuf = self.pixbuf.scale_simple(w, h, GdkPixbuf.InterpType.BILINEAR)
            self.image.set_from_pixbuf(pixbuf)
            self.image_width = pixbuf.get_width()
            self.image_height = pixbuf.get_height()

    def _open_image(self):
        filename = self.files[self.index]

        self.pixbuf = GdkPixbuf.Pixbuf()
        self.pixbuf = self.pixbuf.new_from_file(filename)
        self.image.set_from_pixbuf(self.pixbuf)
        self.image_width = self.pixbuf.get_width()
        self.image_height = self.pixbuf.get_height()

        self._on_resize()
        return True

    def previous_image(self):
        self.index -= 1
        if self.index <= -1:
            self.index = 0
            return True
        self._open_image()

    def next_image(self):
        self.index += 1
        if self.index >= len(self.files):
            self.index = len(self.files) - 1
            return True
        self._open_image()
        self._scroll_up()

    def _scroll_up(self):
        adj = Gtk.Adjustment()
        adj.set_value(0.0)
        self.scrolledwindow.set_vadjustment(adj)


def main():
    directory = sys.argv[1]
    ext = ('.jpg', '.jpe', '.jpeg', '.png', )
    images = [os.path.join(directory, f) for f in sorted(os.listdir(directory)) if f.lower().endswith(ext)]

    win = Comic(images)
    win.window.show_all()
    Gdk.threads_enter()
    Gtk.main()
    Gdk.threads_leave()


if __name__ == "__main__":
    sys.exit(main())

0 个答案:

没有答案