2013-02-08 31 views
6

trên chương trình GTK3 bằng Python Tôi đã cài đặt nhật ký. Đây là một TextView với TextBuffer trong một ScrolledWindow. Với một thói quen, tôi thêm một dòng mới vào nhật ký này. Sau đó nó sẽ di chuyển đến dòng cuối cùng.Cuộn đến cuối ScrolledWindow/TextView

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

Nó sẽ giống như thế này: http://www.physik.tu-dresden.de/~s9472632/log_manual.png

Nhưng nó không hoạt động. Tôi đã thử đoạn mã sau.

# 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) 

Ảnh: http://www.physik.tu-dresden.de/~s9472632/log_scroll.png

Dường như bốn đối số cuối cùng của scroll_to * (within_margin, use_align, xalign, yalign) không có ảnh hưởng của các kết quả.

Cách hoạt động?

Tạm biệt Markus

+0

Đảm bảo bạn đang sử dụng phương thức thêm cho trẻ em có khả năng cuộn gốc. Đây là 'container_add' trong C api. – ergosys

Trả lời

5

Vì vậy, tôi nghĩ rằng tôi biết sự cố. Tôi nghĩ rằng bạn đã kết nối tín hiệu sai để TextView chưa yêu cầu kích thước mới. Đoạn mã dưới đây sử dụng tín hiệu size-allocate của TextView và nó hoạt động như một nét duyên dáng.

#!/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() 
2

Tôi vừa tạo điều này và làm cho dòng scroll_to_mark hoạt động. Tôi tin rằng sự cố của bạn đã đặt 'use_align' thành False. Điểm mấu nên đọc:

self.textview.scroll_to_mark (self.textbuffer.get_insert(), 0.0, True, 0,5, 0,5)

1

Đối với 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); 
} 
Các vấn đề liên quan