Python GTK - 刷新 table/scrollwindow

Python GTK - refreshing a table/scrollwindow

在这个简单的程序中,我正在绘制一个 window,添加一个搜索框,为用户获取搜索词,在 postgreSQL 数据库中查找并显示结果。它在一定程度上起作用 - 当用户输入第二个查询时。

我尝试了两种不同的方法,但每种方法都会出现不同的问题。在第一种方式中(第 32-35 行 http://pastebin.com/q5bnLxaB),我在 main 中创建输出 window 并将其传递给搜索函数。它崩溃并显示 gtk_scrolled_window_add:断言 'child_widget == NULL' 失败。我想是因为我将树添加到 window 中,因为它已经完成了。要解决此问题,我需要以某种方式重置 window。

在第二种方式(第 56-58 行)中,我只在搜索功能中添加了输出 window,所以它不再有这个崩溃问题。但是,window 本身不会更新第二次或后续搜索的结果。

这些方法中哪一种最明智?我还需要考虑下一步是在每个搜索词旁边添加一个可点击的按钮,它将显示每个返回结果的扩展数据。

顺便说一句,在这两种情况下,输出 window 在输入搜索之前不会出现。它不妨碍功能,但对我来说很奇怪。

#!/usr/bin/python
from gi.repository import Gtk
from gi.repository.GdkPixbuf import PixbufLoader
import urllib2
import psycopg2
import sys

class NotebookWindow(Gtk.Window):

    def __init__(self):
        Gtk.Window.__init__(self, title="Rugby Database")

        #Create Application Window
        self.set_border_width(10)
        self.set_default_size(800, 600)
        self.set_position(Gtk.WindowPosition.CENTER)

        #Add external container (box)
        vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6)
        self.add(vbox)

        #Add tabbed window
        nbook = Gtk.Notebook()
        vbox.pack_start(nbook, True, True, 0)
        nbook.show()

        #Add Main tab
        label = Gtk.Label()
        label.set_markup("<b><big>Main</big></b>")
        table = Gtk.Table(rows=40, columns=10)

        #Add Results field
        #results_box = Gtk.ScrolledWindow()
        #results_box.set_vexpand(True)
        #table.attach(results_box, 0, 1, 1, 39, xpadding=5, ypadding=5)

        #Add Search box
        entry = Gtk.Entry()
        entry.set_property("secondary-icon-stock", Gtk.STOCK_FIND)
        entry.connect("icon-press", self.on_search_button)
        #entry.connect("activate", self.on_search_enter, results_box)
        entry.connect("activate", self.on_search_enter, table)
        table.attach(entry, 0, 1, 0, 1, xpadding=5)

        nbook.append_page(table, label)


    def on_search_button(self, entry, icon, event):
        search = entry.get_text()
        print("Search for " + search)

    def on_search_enter(self, entry, table): #changed from results_box
        store = Gtk.ListStore(str, str, str)
        tree = Gtk.TreeView(store)
        ##
        results_box = Gtk.ScrolledWindow()
        results_box.set_vexpand(True)
        table.attach(results_box, 0, 1, 1, 39, xpadding=5, ypadding=5)
        ##
        search = entry.get_text()
        search = search.replace("'","''") #deal with apostrophes
        entry.set_text("")
        print("Search for " + search)
        result = self.lookup_player(search)
        print result
        if len(result) > 0:
           for i in range(0, len(result)):
            store.append([result[i][0],result[i][1],str(result[i][4])])
            print result[i][0],result[i][1],result[i][2],result[i][3],result[i][4],result[i][5],result[i][6],result[i][7],result[i][8]
        else:
           print "No players found"

        #Add column for last name
        renderer = Gtk.CellRendererText()
        column = Gtk.TreeViewColumn("Last Name")
        column.pack_start(renderer, True)
        column.add_attribute(renderer, "text", 0)
        tree.append_column(column)

        #Add column for first name
        renderer = Gtk.CellRendererText()
        column = Gtk.TreeViewColumn("First Name")
        column.pack_start(renderer, True)
        column.add_attribute(renderer, "text", 1)
        tree.append_column(column)

        #Add column for icon
        renderer = Gtk.CellRendererPixbuf()
        column = Gtk.TreeViewColumn("Show")
        column.pack_start(renderer, True)
        column.add_attribute(renderer, "stock-id", 2)
        tree.append_column(column)

        results_box.add(tree)
        table.show_all()
        tree.show_all()

    def on_click_edit(self, button):
        print("Editing Player")

    def lookup_player(self, pstring):
        try:
            con = psycopg2.connect(database='Rugby', user='postgres', password = '1234')
            cur = con.cursor()
            search = "select pl.lastname, pl.firstname, pl.height, pl.weight, to_char(pl.dob, 'DD/MM/YYYY'), cl.name, pl.injury_id, to_char(pl.suspendeduntil, 'DD/MM/YYYY'), pl.photo from player pl inner join club cl on cl.id = pl.currentclub_id where firstname ilike '%s' or lastname ilike '%s'" % (pstring, pstring)
            cur.execute(search)
            result = cur.fetchall()
            return result

        except psycopg2.DatabaseError, e:
            print 'Error %s' % e
            sys.exit(1)

        finally:
            if con:
                con.close()

win = NotebookWindow()
win.connect("delete-event", Gtk.main_quit)
win.show_all()


Gtk.main()

注意 这是后续问题 因为最初的查询已经得到回答,范围也因此发生了变化(顺便说一句,非常感谢所有帮助过的人!)

你应该在 __init__() 中尽你所能。这包括创建商店(作为实例变量,以便您可以在搜索处理程序中使用它)、创建所有小部件(ScrolledWindow 和 TreeView)以及将列添加到树视图。

在搜索处理程序中,您只应在 ListStore 上调用 clear()(以删除所有旧结果),然后将新结果添加到存储中。