Python GTK-刷新表/滚动窗口

Python GTK-刷新表/滚动窗口,python,postgresql,gtk,Python,Postgresql,Gtk,在这个简单的程序中,我画了一个窗口,添加了一个搜索框,为用户获取一个搜索词,在postgreSQL数据库中查找并显示结果。当用户输入第二个查询时,它会一直起作用 我试过两种不同的方法,但每种方法都会带来不同的问题。第一种方式(第32-35行)是在main中创建输出窗口,并将其传递给search函数。它在gtk_滚动窗口_添加时崩溃:断言'child_widget==NULL'失败。我想是因为我正在将树添加到窗口,而它已经完成了。要解决这个问题,我需要以某种方式重置窗口 在第二种方式中(第56-5

在这个简单的程序中,我画了一个窗口,添加了一个搜索框,为用户获取一个搜索词,在postgreSQL数据库中查找并显示结果。当用户输入第二个查询时,它会一直起作用

我试过两种不同的方法,但每种方法都会带来不同的问题。第一种方式(第32-35行)是在main中创建输出窗口,并将其传递给search函数。它在gtk_滚动窗口_添加时崩溃:断言'child_widget==NULL'失败。我想是因为我正在将树添加到窗口,而它已经完成了。要解决这个问题,我需要以某种方式重置窗口

在第二种方式中(第56-58行),我只在搜索函数中添加了输出窗口,因此它不再有这种崩溃问题。但是,窗口本身不会随着第二次或后续搜索的结果而更新

这些方法中哪一种似乎最明智?我还需要考虑下一步是在每个搜索项旁边添加一个可点击的按钮,它将显示每个返回结果的扩展数据。 顺便说一句,在这两种情况下,在输入搜索之前不会出现输出窗口。这并不妨碍功能,但对我来说很奇怪

#!/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()
#/usr/bin/python
从gi.repository导入Gtk
从gi.repository.GdkPixbuf导入PixbufLoader
导入urllib2
导入psycopg2
导入系统
课堂笔记簿窗口(Gtk.Window):
定义初始化(自):
Gtk.Window.\uuuu init\uuuu(self,title=“橄榄球数据库”)
#创建应用程序窗口
自行设置边框宽度(10)
设置默认大小(800600)
自我设置位置(Gtk.WindowPosition.CENTER)
#添加外部容器(盒子)
vbox=Gtk.Box(方向=Gtk.orientation.VERTICAL,间距=6)
self.add(vbox)
#添加选项卡式窗口
nbook=Gtk.Notebook()
vbox.pack_start(nbook,True,True,0)
nbook.show()
#添加主选项卡
label=Gtk.label()
label.set_标记(“主”)
table=Gtk.table(行=40,列=10)
#添加结果字段
#结果_box=Gtk.ScrolledWindow()
#结果_box.set _vexpand(真)
#表.附件(结果框,0,1,1,39,xpadding=5,ypadding=5)
#添加搜索框
entry=Gtk.entry()
entry.set_属性(“辅助图标库存”,Gtk.stock_FIND)
entry.connect(“图标按下”,self.on搜索按钮)
#entry.connect(“激活”,self.on\u搜索\u输入,结果\u框)
entry.connect(“激活”,self.on\u search\u enter,table)
table.attach(条目0,1,0,1,xpadding=5)
nbook.append_页面(表格、标签)
def on_search_按钮(自身、条目、图标、事件):
search=entry.get_text()
打印(“搜索”+搜索)
_search_enter(self、entry、table)上的def:#从结果框中更改
store=Gtk.ListStore(str,str,str)
tree=Gtk.TreeView(商店)
##
结果_box=Gtk.ScrolledWindow()
结果_box.set _vexpand(真)
表.附件(结果框,0,1,1,39,xpadding=5,ypadding=5)
##
search=entry.get_text()
search=search.replace(“,”)#处理撇号
entry.set_文本(“”)
打印(“搜索”+搜索)
结果=self.lookup\u播放器(搜索)
打印结果
如果len(结果)>0:
对于范围(0,len(结果))中的i:
store.append([result[i][0],result[i][1],str(result[i][4]))
打印结果[i][0]、结果[i][1]、结果[i][2]、结果[i][3]、结果[i][4]、结果[i][5]、结果[i][6]、结果[i][7]、结果[i][8]
其他:
打印“未找到玩家”
#为姓氏添加列
renderer=Gtk.CellRendererText()
column=Gtk.TreeViewColumn(“姓氏”)
column.pack_start(渲染器,True)
添加属性(渲染器,“文本”,0)
tree.append_列(列)
#为名字添加列
renderer=Gtk.CellRendererText()
column=Gtk.TreeViewColumn(“名字”)
column.pack_start(渲染器,True)
添加属性(渲染器,“文本”,1)
tree.append_列(列)
#为图标添加列
renderer=Gtk.CellRendererPixbuf()
列=Gtk.TreeViewColumn(“显示”)
column.pack_start(渲染器,True)
添加_属性(渲染器,“股票id”,2)
tree.append_列(列)
结果框。添加(树)
表.全部显示()
tree.show_all()
def on_单击编辑(自我,按钮):
打印(“编辑播放器”)
def查找\u播放机(自身、pstring):
尝试:
con=psycopg2.connect(database='Rugby',user='postgres',password='1234')
cur=con.cursor()
search=“选择pl.lastname,pl.firstname,pl.height,pl.weight,to_char(pl.dob,'DD/MM/yyyyy')、cl.name,pl.injury _id,to_char(pl.suspendedduntil,'DD/MM/yyyyy')、pl.photo from player pl.internal join club cl on cl.id=pl.currentclub_id,其中firstname类似'%s'或lastname类似'%s'(pstring,pstring)
当前执行(搜索)
结果=cur.fetchall()
返回结果
除psycopg2.DatabaseError外,e:
打印“错误%s”%e
系统出口(1)
最后:
如果反对:
con.close()
win=NotebookWindow()
win.connect(“删除事件”,Gtk.main_退出)
赢,全力以赴
Gtk.main()
注意这是对
由于最初的查询已经得到了回答,范围也因此发生了变化(顺便说一句,感谢所有帮助过它的人!)

您应该在
\uuuu init\uuu()
中尽您所能。这包括创建存储(作为实例变量,以便您可以在搜索处理程序中使用它)、创建所有小部件(ScrolledWindow和TreeView)以及将列添加到TreeView

在搜索处理程序中,您应该只调用ListStore上的
clear()
(以删除任何旧结果