ScrolledWindow 通过拖动滚动(模拟触摸屏上的手指)
ScrolledWindow scroll by drag (simulate finger on touchscreen)
我正在使用 python 和 GTK+3 构建一个应用程序,并使用 ScrolledWindow 中的 TreeView 以表格形式显示数据。
可以将滚动的 window 配置为通过拖动树视图行来执行滚动吗?就像我们在(移动)触摸屏上所做的那样。
在文档中,ScrolledWindows 具有动态滚动 属性 但是:
- 不知道怎么用
- 我没有触摸屏,想用鼠标模拟一下
我不需要跨平台的解决方案,只需要 Ubuntu。
谢谢。
一个可能的解决方案是连接到 button press event
和 button release event
。这将传递小部件(树视图)和一个事件。该事件具有 .x 和 .y 属性,可用于检测鼠标移动的距离。
事件属性的文档已关闭:(
更新:
我想出了如何完全按照您的要求进行操作。观察 button press event
、button release event
和 motion notify event
必须在树视图上。这是使用 Gtk Builder。
glade.ui文件的代码:
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.18.3 -->
<interface>
<requires lib="gtk+" version="3.0"/>
<object class="GtkListStore" id="liststore1">
<columns>
<!-- column-name gchararray1 -->
<column type="gchararray"/>
</columns>
</object>
<object class="GtkWindow" id="window">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="title" translatable="yes">window</property>
<property name="default_width">500</property>
<property name="default_height">400</property>
<signal name="destroy" handler="on_window_destroy" swapped="no"/>
<child>
<object class="GtkScrolledWindow" id="scrolledwindow1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="events"/>
<property name="shadow_type">in</property>
<child>
<object class="GtkTreeView" id="treeview1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="events"/>
<property name="model">liststore1</property>
<signal name="button-press-event" handler="button_press_event" swapped="no"/>
<signal name="button-release-event" handler="button_release_event" swapped="no"/>
<signal name="motion-notify-event" handler="motion_notify_event" swapped="no"/>
<child internal-child="selection">
<object class="GtkTreeSelection" id="treeview-selection1"/>
</child>
<child>
<object class="GtkTreeViewColumn" id="treeviewcolumn1">
<property name="title" translatable="yes">column</property>
<child>
<object class="GtkCellRendererText" id="cellrenderertext1"/>
<attributes>
<attribute name="text">0</attribute>
</attributes>
</child>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</interface>
.py文件代码:
#!/usr/bin/python
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, GdkPixbuf, Gdk
import os, sys
UI_FILE = "glade.ui"
class GUI:
def __init__(self):
self.builder = Gtk.Builder()
self.builder.add_from_file(UI_FILE)
self.builder.connect_signals(self)
liststore = self.builder.get_object('liststore1')
for i in range (100):
liststore.append([str(i)])
self.v_scroll = self.builder.get_object('scrolledwindow1').get_vadjustment ()
self.mouse_down = False
self.previous_y = 0
self.previous_position = 0
window = self.builder.get_object('window')
window.show_all()
def button_press_event (self, treeview, event):
if event.button == 1:
self.mouse_down = True
self.previous_y = event.y
self.previous_position = self.v_scroll.get_value()
def button_release_event (self, treeview, event):
self.mouse_down = False
def motion_notify_event (self, scrolled_window, event):
if self.mouse_down == False:
return
current_y = event.y
y_movement = (self.previous_y - current_y)
scroll_position = (self.previous_position + y_movement)
self.v_scroll.set_value(scroll_position)
def on_window_destroy(self, window):
Gtk.main_quit()
def main():
app = GUI()
Gtk.main()
if __name__ == "__main__":
sys.exit(main())
变量名应该很好地解释了它们的作用。如果我理解有误,请纠正我。
我正在使用 python 和 GTK+3 构建一个应用程序,并使用 ScrolledWindow 中的 TreeView 以表格形式显示数据。
可以将滚动的 window 配置为通过拖动树视图行来执行滚动吗?就像我们在(移动)触摸屏上所做的那样。
在文档中,ScrolledWindows 具有动态滚动 属性 但是:
- 不知道怎么用
- 我没有触摸屏,想用鼠标模拟一下
我不需要跨平台的解决方案,只需要 Ubuntu。
谢谢。
一个可能的解决方案是连接到 button press event
和 button release event
。这将传递小部件(树视图)和一个事件。该事件具有 .x 和 .y 属性,可用于检测鼠标移动的距离。
事件属性的文档已关闭:(
更新:
我想出了如何完全按照您的要求进行操作。观察 button press event
、button release event
和 motion notify event
必须在树视图上。这是使用 Gtk Builder。
glade.ui文件的代码:
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.18.3 -->
<interface>
<requires lib="gtk+" version="3.0"/>
<object class="GtkListStore" id="liststore1">
<columns>
<!-- column-name gchararray1 -->
<column type="gchararray"/>
</columns>
</object>
<object class="GtkWindow" id="window">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="title" translatable="yes">window</property>
<property name="default_width">500</property>
<property name="default_height">400</property>
<signal name="destroy" handler="on_window_destroy" swapped="no"/>
<child>
<object class="GtkScrolledWindow" id="scrolledwindow1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="events"/>
<property name="shadow_type">in</property>
<child>
<object class="GtkTreeView" id="treeview1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="events"/>
<property name="model">liststore1</property>
<signal name="button-press-event" handler="button_press_event" swapped="no"/>
<signal name="button-release-event" handler="button_release_event" swapped="no"/>
<signal name="motion-notify-event" handler="motion_notify_event" swapped="no"/>
<child internal-child="selection">
<object class="GtkTreeSelection" id="treeview-selection1"/>
</child>
<child>
<object class="GtkTreeViewColumn" id="treeviewcolumn1">
<property name="title" translatable="yes">column</property>
<child>
<object class="GtkCellRendererText" id="cellrenderertext1"/>
<attributes>
<attribute name="text">0</attribute>
</attributes>
</child>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</interface>
.py文件代码:
#!/usr/bin/python
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, GdkPixbuf, Gdk
import os, sys
UI_FILE = "glade.ui"
class GUI:
def __init__(self):
self.builder = Gtk.Builder()
self.builder.add_from_file(UI_FILE)
self.builder.connect_signals(self)
liststore = self.builder.get_object('liststore1')
for i in range (100):
liststore.append([str(i)])
self.v_scroll = self.builder.get_object('scrolledwindow1').get_vadjustment ()
self.mouse_down = False
self.previous_y = 0
self.previous_position = 0
window = self.builder.get_object('window')
window.show_all()
def button_press_event (self, treeview, event):
if event.button == 1:
self.mouse_down = True
self.previous_y = event.y
self.previous_position = self.v_scroll.get_value()
def button_release_event (self, treeview, event):
self.mouse_down = False
def motion_notify_event (self, scrolled_window, event):
if self.mouse_down == False:
return
current_y = event.y
y_movement = (self.previous_y - current_y)
scroll_position = (self.previous_position + y_movement)
self.v_scroll.set_value(scroll_position)
def on_window_destroy(self, window):
Gtk.main_quit()
def main():
app = GUI()
Gtk.main()
if __name__ == "__main__":
sys.exit(main())
变量名应该很好地解释了它们的作用。如果我理解有误,请纠正我。