使用Glade的Python GTK列表视图

4 投票
2 回答
6942 浏览
提问于 2025-04-16 11:24

我现在正在为我的Linux桌面开发一个应用程序,这个程序可以读取我的Garmin Forerunner运动手表的数据,解析那些格式不太规范的XML文件,然后把数据写入MySQL数据库表里。因为我对Python和GTK不是很熟悉,所以我用Glade这个图形界面设计工具来处理界面部分。现在遇到一个问题,有一些数据并不是来自手表的,我想在写入数据库之前添加这些数据。我会读取或计算圈数、圈的距离、圈速和圈的持续时间。不过,我希望能在界面上查看每一圈,并用下拉框来分类,比如标记为“速度训练”、“轻松跑”等等。从我看到的资料来看,使用列表视图(listview)是个不错的选择。

但是,我看到的所有示例和文档都是通过代码来构建列表视图的,而不是通过Glade来创建。我想遍历我的列表(圈数 [类型:整数]、持续时间 [类型:字符串]、距离 [类型:浮点数]、圈速 [类型:字符串]——注意,我把时间存储为字符串,以便写入数据库的时间/日期字段),然后把这些字段填充到列表视图中(我假设这样做是对的,如果错了请纠正我),同时还要有一个下拉框来进行分类。接着,我会把列表视图中的每一行写入数据库。

有没有人知道有什么示例可以帮助我,或者有没有人有具体的想法?

更新:

我基本上想知道,如果我通过Glade在图形界面上放置一个列表视图或树视图,我该如何用以下列来填充它:圈ID(整数)、距离(浮点数)、持续时间(字符串),还有一个下拉框让我选择这是什么类型的圈。这是第一步。

一旦我填充了列表,我该如何引用每一行,以便将其写入数据库表中?

2 个回答

0

对于那些注意到'column0'和'column1'是一样的,只需将 text=0 改成 text=1,就像下面这样:

column = gtk.TreeViewColumn('column1', gtk.CellRendererText(), text=1)

http://www.pygtk.org/docs/pygtk/class-gtktreeviewcolumn.html#constructor-gtktreeviewcolumn

3

看看下面这个例子是否适合你。它从一个glade文件中加载用户界面,并使用sqlite数据库来存储项目。

脚本:

import gtk
import sqlite3

class  ListViewTestApp:
    def __init__(self):
        builder = gtk.Builder()
        builder.add_from_file('listview_test.glade')
        builder.connect_signals(self)

        self.model = builder.get_object('list_items')
        self.list = builder.get_object('items_view')

        column = gtk.TreeViewColumn('column0', gtk.CellRendererText(), text=0)   
        column.set_clickable(True)   
        column.set_resizable(True)   
        self.list.append_column(column)

        column = gtk.TreeViewColumn('column1', gtk.CellRendererText(), text=0)   
        column.set_clickable(True)   
        column.set_resizable(True)   
        self.list.append_column(column)

        self.create_database()
        self.load_list_items()

        window = builder.get_object('main_window')
        window.show_all()

    def create_database(self):
        self.engine = sqlite3.connect(':memory:')
        self.engine.execute('create table test_table ' + \
            '(id INTEGER NOT NULL PRIMARY KEY, test_field0 VARCHAR(30), test_field1 VARCHAR(30))');
        self.add_new_line('test0', 'test000');
        self.add_new_line('test1', 'test111');

    def load_list_items(self):
        self.model.clear()        
        result = self.engine.execute('select * from test_table');
        for row in result: 
            self.model.append([row[1], row[2]])

    def add_new_line(self, test0, test1):
        query = 'INSERT INTO test_table (test_field0, test_field1) VALUES ("{0}", "{1}")'\
            .format(test0, test1)
        self.engine.execute(query)

    def on_load_button_clicked(self, widget):
        self.load_list_items()

    def on_add_line_button_clicked(self, widget):
        id = len(self.model)
        self.add_new_line('new_item{0}'.format(id), 'new__item{0}'.format(id));
        self.load_list_items()

if __name__ == "__main__":
    ListViewTestApp()
    gtk.main()

glade文件(listview_test.glade):

<?xml version="1.0" encoding="UTF-8"?>
<interface>
  <requires lib="gtk+" version="2.16"/>
  <!-- interface-naming-policy project-wide -->
  <object class="GtkListStore" id="list_items">
    <columns>
      <!-- column-name column0 -->
      <column type="gchararray"/>
      <!-- column-name column1 -->
      <column type="gchararray"/>
    </columns>
  </object>
  <object class="GtkWindow" id="main_window">
    <child>
      <object class="GtkFixed" id="fixed1">
        <property name="visible">True</property>
        <child>
          <object class="GtkTreeView" id="items_view">
            <property name="width_request">270</property>
            <property name="height_request">250</property>
            <property name="visible">True</property>
            <property name="can_focus">True</property>
            <property name="model">list_items</property>
          </object>
          <packing>
            <property name="x">200</property>
            <property name="y">20</property>
          </packing>
        </child>
        <child>
          <object class="GtkButton" id="load_button">
            <property name="label" translatable="yes">load</property>
            <property name="width_request">100</property>
            <property name="height_request">40</property>
            <property name="visible">True</property>
            <property name="can_focus">True</property>
            <property name="receives_default">True</property>
            <signal name="clicked" handler="on_load_button_clicked"/>
          </object>
          <packing>
            <property name="x">54</property>
            <property name="y">49</property>
          </packing>
        </child>
        <child>
          <object class="GtkButton" id="add_line_button">
            <property name="label" translatable="yes">add line</property>
            <property name="width_request">100</property>
            <property name="height_request">40</property>
            <property name="visible">True</property>
            <property name="can_focus">True</property>
            <property name="receives_default">True</property>
            <property name="xalign">0.41999998688697815</property>
            <property name="yalign">0.46000000834465027</property>
            <signal name="clicked" handler="on_add_line_button_clicked"/>
          </object>
          <packing>
            <property name="x">54</property>
            <property name="y">113</property>
          </packing>
        </child>
      </object>
    </child>
  </object>
</interface>

希望这对你有帮助,祝好!

撰写回答