【问题标题】:Scroll to end of ScrolledWindow/TextView滚动到 ScrolledWindow/TextView 的末尾
【发布时间】:2013-02-08 10:02:10
【问题描述】:

在一个带有 Python 的 GTK3 程序上,我实现了一个日志。这是一个在 ScrolledWindow 中带有 TextBuffer 的 TextView。通过例程,我在此日志中添加了一个新行。之后它应该滚动到最后一行。

def append_log(self, line):
    self.textbuffer.insert(self.textbuffer.get_end_iter(), "\n"+line, -1)
    # scrolling down

应该是这样的:http://www.physik.tu-dresden.de/~s9472632/log_manual.png

但它不起作用。我试过下面的代码。

# nothing happens
adj = self.scrolledwindow.get_vadjustment()
adj.set_value(adj.get_upper()-adj.get_page_size())    # same without subtraction (only upper or page_size)
self.scrolledwindow.set_vadjustment(adj)              # with and without this line

.

# nothing happens
self.textview.scroll_to_iter(self.textbuffer.get_end_iter(), 0.0, False, 0.5, 0.5)

.

# works a bit but scroll bars cover the text (see picture below)
self.textview.scroll_to_mark(self.textbuffer.get_insert(), 0.0, False, 0.5, 0.5)

图片:http://www.physik.tu-dresden.de/~s9472632/log_scroll.png

scroll_to* 的最后四个参数(within_margin、use_align、xalign、yalign)似乎对结果没有影响。

它是如何工作的?

再见马库斯

【问题讨论】:

  • 确保您对具有本机滚动功能的子项使用 add 方法。这是 C api 中的container_add

标签: python gtk


【解决方案1】:

所以我想我知道问题所在。我认为您连接了错误的信号,因此TextView 尚未请求新尺寸。下面的代码使用TextViewsize-allocate 信号,它就像一个魅力。

#!/usr/bin/env python

from gi.repository import Gtk, GObject


class W(Gtk.Window):

    def __init__(self):

        super(W, self).__init__()
        self.connect("destroy", Gtk.main_quit)
        self.set_default_size(200, 400)

        self._msg_i = 0
        self._sw = Gtk.ScrolledWindow()
        self.add(self._sw)

        self._tw = Gtk.TextView()
        self._tb = self._tw.get_buffer()

        self._sw.add_with_viewport(self._tw)
        #The signal should at least be connected after the scrolled window
        #is created, since the callback works on it.
        self._tw.connect("size-allocate", self._autoscroll)

        GObject.timeout_add(400, self.sim_log)  # Invokes spamming
        self.show_all()

    def sim_log(self, *args):
        """A simple spamming function to emulate some sort of logging"""
        self._msg_i += 1
        i = self._tb.get_end_iter()
        self._tb.insert(i, "\n* Message {0} recieved!".format(self._msg_i), -1)
        return True

    def _autoscroll(self, *args):
        """The actual scrolling method"""
        adj = self._sw.get_vadjustment()
        adj.set_value(adj.get_upper() - adj.get_page_size())


if __name__ == "__main__":

    w = W()
    Gtk.main()

【讨论】:

  • adj.set_value(adj.get_upper() - adj.get_page_size()) 只需滚动到现在显示的第一行。最好向下滚动
【解决方案2】:

我刚刚拥有了这个并让 scroll_to_mark 线工作。我相信您的问题是将“use_align”设置为 False。该行应为:

self.textview.scroll_to_mark(self.textbuffer.get_insert(), 0.0, True, 0.5, 0.5)

【讨论】:

    【解决方案3】:

    对于 gtkmm 3.0/C++11:

    void append(std::string s) {
      textbuffer->insert(textbuffer->end(), s.c_str());
    
      // Wait for Gui to Redraw with added line to buffer
      while (gtk_events_pending())
        gtk_main_iteration_do(false);
    
      // Scoll to end of Buffer
      auto it = textbuffer->get_iter_at_line(textbuffer->get_line_count());
      TextView1.scroll_to(it);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-28
      相关资源
      最近更新 更多