我目前正在编写一个类似于任务管理器的程序(类似于 Windows 的程序),并且我在 gtk+ 3 中使用树形视图作为 GUI。问题是,通过使树视图更新“实时”,滚动条停止正常运行。每次刷新树视图时,滚动条都会转到页面顶部。这是用于更新树视图的行:
GObject.timeout_add_seconds(1, self.update_treeview)
这是函数 update_treeview:
def update_treeview(self):
self.process_list_store.clear()
p_list = create_list(self.properties, create_list_of_processes())
for p in p_list:
self.process_list_store.append(list(p))
return True
如果重要的话,这就是我创建树视图的方式:
def create_treeview(process_list_store):
treeview = gtk.TreeView(process_list_store)
for i, col_title in enumerate(['Name', 'pid', 'Username', 'Memory usage', 'Cpu usage']):
renderer = gtk.CellRendererText()
column = gtk.TreeViewColumn(col_title, renderer, text=i)
column.set_sort_column_id(i)
column.set_min_width(110)
column.set_resizable(i)
treeview.append_column(column)
return treeview
树视图位于滚动窗口对象内:
self.scrolled_window = gtk.ScrolledWindow(hexpand=True, vexpand=True)
self.scrolled_window.set_policy(gtk.PolicyType.NEVER, gtk.PolicyType.AUTOMATIC)
我寻找可能更新树视图的其他方法,但我无法找到解决方案。我将不胜感激任何帮助来解决这个问题,谢谢!
编辑:这是完整的代码:
import psutil
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk as gtk
from gi.repository import GObject
class MainWindow(gtk.Window):
def __init__(self):
gtk.Window.__init__(self, title="Task Manager")
self.set_default_size(1000, 500)
#basic objects in the program
self.set_border_width(10)
self.notebook = gtk.Notebook()
self.grid1 = gtk.Grid(row_spacing=20)
self.notebook.set_scrollable(True)
self.add(self.notebook)
#Processes Tab
self.tab1 = gtk.Box()
self.set_border_width(10)
self.notebook.append_page(self.tab1, gtk.Label("Processes"))
self.properties = ['name', 'pid', 'username', 'memory_percent', 'cpu_percent']
p_list = create_list(self.properties, create_list_of_processes())
print p_list
#create a list store object for the tree view
self.process_list_store = gtk.ListStore(str, int, str, str, str)
for p in p_list:
self.process_list_store.append(list(p))
#create a window that can be scrolled
self.scrolled_window = gtk.ScrolledWindow(hexpand=True, vexpand=True)
self.scrolled_window.set_policy(gtk.PolicyType.NEVER, gtk.PolicyType.AUTOMATIC)
self.grid1.attach(self.scrolled_window, 0, 0, 8, 10)
#create a tree view and add it to the window
self.tree_view = create_treeview(self.process_list_store)
self.scrolled_window.add(self.tree_view)
self.tab1.add(self.grid1)
GObject.timeout_add_seconds(1, self.update_treeview)
def update_treeview(self):
self.process_list_store.clear()
p_list = create_list(self.properties, create_list_of_processes())
for p in p_list:
self.process_list_store.append(list(p))
return True
#create a list of dictionaries of processes and info about them
def create_list_of_processes():
list_of_processes = []
for proc in psutil.process_iter():
try:
pinfo = proc.as_dict(attrs=['pid', 'name', 'username', 'memory_percent', 'cpu_percent'])
except psutil.NoSuchProcess:
pass
else:
if not pinfo['username']:
pinfo['username'] = 'SYSTEM'
pinfo['cpu_percent'] = str(pinfo['cpu_percent'] / psutil.cpu_count()) + '%'
pinfo['memory_percent'] = str(pinfo['memory_percent'])[0:6]
pinfo['memory_percent'] = str(pinfo['memory_percent']) + '%'
list_of_processes.append(pinfo)
return list_of_processes
#create a tree view object
def create_treeview(process_list_store):
treeview = gtk.TreeView(process_list_store)
for i, col_title in enumerate(['Name', 'pid', 'Username', 'Memory usage', 'Cpu usage']):
renderer = gtk.CellRendererText()
column = gtk.TreeViewColumn(col_title, renderer, text=i)
column.set_sort_column_id(i)
column.set_min_width(110)
column.set_resizable(i)
treeview.append_column(column)
return treeview
#create a list based on the desired properties
def create_list(properties, p_dict):
p_list = []
for dict in p_dict:
small_p_list = []
for prop in properties:
small_p_list.append(dict[prop])
p_list.append(small_p_list)
return p_list
def main():
window = MainWindow()
window.connect("delete-event", gtk.main_quit)
window.show_all()
gtk.main()
if __name__ == '__main__':
main()