5

Gtk + 3では、TreeModelネストされた情報を格納するためにを使用しており、それをaCellRendererTextと。で表示しCellRendererToggleます。ユーザーはすべてのトグルボタンをクリックできます。ネストされたボタンがあり、それらが同じ状態にない場合は、上位レベルのものに「一貫性のない」状態を反映させたいと思います。このプロパティを1つの要素に設定するにはどうすればよいですか?

より明確にするために、Transmissionbittorrentクライアントから達成したいことの例: ここに画像の説明を入力してください

セルレンダラーのすべてのボタンを一貫性のない状態に設定する方法は知っていますが、myCellRendererToggle.set_properties(inconsistent=True)ここから1つの要素にアクセスできないようです。

TreeStoreモデルの特定の行にアクセスする方法は知っていますが、設定できるのは«True»と«False»の値のみです。

私のコードは公式ドキュメントにかなり近いので、あなたはそれを手伝うことができます:https : //python-gtk-3-tutorial.readthedocs.org/en/latest/cellrenderers.html#cellrenderertoggle(私は代わりにtreeStoreを使用しますlistStore)

そしてこれは私のコードです:

class HelloMyApp:

def __init__(self):

    # Set the Glade file
    self.builder = Gtk.Builder()
    self.builder.add_from_file(GLADEFILE)


    dic = {
        "on_button1_clicked" : self.btnValidate_clicked,
        "on_MainWindow_destroy" : self.quit,
        "on_window1_delete_event" : self.quit,

        }

    self.builder.connect_signals(dic)

    window = self.builder.get_object("window1")

    treeview1 = self.builder.get_object("treeview1")

    ######## This is my model : it stores a string and a boolean. #########
    self.treeModel = Gtk.TreeStore(str, bool)

    # Example on how to insert data in the model
    treeIter = self.treeModel.append(None, ['example one', True])
    self.treeModel.append(treeIter, [' simple elt', True])
    treeIter = self.treeModel.append(treeIter, ['example two', False])
    self.treeModel.append(treeIter, ['under example two', True])


    select = treeview1.get_selection()
    select.set_mode(Gtk.SelectionMode.BROWSE)

    select.connect("changed", self.on_tree_selection_changed, buf) 

    # Using one column of text and another column with the toggle buttons
    renderer = Gtk.CellRendererText()
    column = Gtk.TreeViewColumn("Title", renderer, text=0)
    treeview1.append_column(column)

    ######  Here is the CellRendereToggle  ################
    renderer_toggle = Gtk.CellRendererToggle()
    renderer_toggle.connect("toggled", self.on_cell_toggled)
    column_toggle = Gtk.TreeViewColumn("Installer", renderer_toggle, active=1)
    treeview1.append_column(column_toggle)

    treeview1.set_model(self.treeModel)


    window.show_all()


if __name__ == "__main__":

    HelloMyApp = HelloMyApp()
    Gtk.main()

ありがとう !

編集:答えるマーカス:わかりません。関数内でCellRendererToggleのプロパティを変更すると、すべての行が変更されます。

ソリューションの編集:Marcuが指摘したように、すべての場合にプロパティを設定する必要があるため、elseパーツを追加しました。

def cellRenderer_func(column, cellRenderer, treeModel, treeIter, userData):
    if 'cat' in treeModel.get_value(treeIter, 0): 
        # it happens only ones in my model, 
        # so here I am in a row I want to change to inconsistent.
        cellRenderer.set_property('inconsistent',True) 
        # I was expecting that changes the box of that row but it affects every row. 

    else: 
        cellRenderer.set_property('inconsistent', False) # and that's ok now.

もう一度やり直さなければなりません。不思議に思う…本当に手動でやらなければならないのだろうか、それはtreeViewの箱から出してすぐに使える機能ではないだろうか?

4

2 に答える 2

4

セルデータ関数を使用して、1つの要素のプロパティを設定することができます。私はまだCでのみこれを行っているので、PyGTKのドキュメントへのリンクしか渡すことができません。PyGObjectのこの機能に関連するドキュメントはまだ見ていません。

PyGTKがここに文書化されているため、このページの下部に例が示されています。PyGTKのセルデータ関数の使用もこの文書で取り上げられています。

たとえば、Transmissionと同じことをしたい場合は、次のようにすることができます。セルデータ関数のパラメータとして現在のiterを受け取るので、そこですべての子をループして、のステータスを確認できます。子供。そうすれば、親ノードでどの状態を設定するかがわかります。ここで重要なのは、セルデータ関数内にプロパティを設定すると、ツリービューのすべての要素ではなく、この単一のセルにのみ影響するということです。

私自身のアプリケーションの視覚的な例も示します。

ここに画像の説明を入力してください

このツリービューに「値」列があります。「メニュー要素」列内の値が「有効」に設定され、「タイプ」列内の値が「オプション」の場合、テキストの代わりにチェックボックスが表示されます(そのような行を強調表示しています)。サンプル画像は、検索結果を強調表示するアクティブな検索も示しています。セルデータ関数を使用すると、両方とも、質問で要求した1つの要素のプロパティを設定できます。

編集

いくつかのサンプルコードを作成しました。重要な点は、セルプロパティは常にすべてのセルに設定されるということです。したがって、「if ...、次にプロパティを設定する」だけでなく、「if、このようにプロパティを設定する、else、このようにプロパティを設定する」。(これは古いPyGTKのドキュメントに基づいていますが、とにかく物事を明確にする必要があります)。

#!/usr/bin/env python

# example basictreeview.py

import pygtk
pygtk.require('2.0')
import gtk

class BasicTreeViewExample:

    def set_status(self, column, cell, model, iter):
        if 'inconsistent' in model.get_value(iter, 0):
            cell.set_property('inconsistent',True) 
        else:
            cell.set_property('inconsistent',False)
        return

    def delete_event(self, widget, event, data=None):
        gtk.main_quit()
        return False

    def __init__(self):
        self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)

        self.window.set_title("Basic TreeView Example")

        self.window.set_size_request(200, 200)

        self.window.connect("delete_event", self.delete_event)

        self.treestore = gtk.TreeStore(str)

        for parent in range(4):
            piter = self.treestore.append(None, ['parent %i' % parent])
            for child in range(3):
                if child == 1:
                    self.treestore.append(piter, ['consistent'])
                else:
                    self.treestore.append(piter, ['inconsistent'])

        self.treeview = gtk.TreeView(self.treestore)

        self.tvcolumn0 = gtk.TreeViewColumn('Column 0')
        self.tvcolumn1 = gtk.TreeViewColumn('Column 1')

        self.treeview.append_column(self.tvcolumn0)
        self.treeview.append_column(self.tvcolumn1)

        self.text = gtk.CellRendererText()
        self.toggle = gtk.CellRendererToggle()

        self.tvcolumn0.pack_start(self.text, True)
        self.tvcolumn1.pack_start(self.toggle, True)

        self.tvcolumn0.add_attribute(self.text, 'text', 0)
        self.tvcolumn1.set_cell_data_func(self.toggle, self.set_status)

        self.window.add(self.treeview)

        self.window.show_all()

def main():
    gtk.main()

if __name__ == "__main__":
    tvexample = BasicTreeViewExample()
    main()
于 2013-02-07T22:51:38.990 に答える
1

最近同じ問題が発生しましたが、モデルの列から直接プロパティを設定する場合は、セルデータ関数は必要ないことがわかりました。それを実現する質問からのコードで必要な更新は、次のようになります。

self.treeModel = Gtk.TreeStore(str, bool, bool)
...
column_toggle = Gtk.TreeViewColumn("Installer", renderer_toggle, active=1, inconsistent=2)

次に、必要に応じて、新しい列に一貫性のない値を設定します。

モデルでセルデータ関数または新しい列を選択するタイミングについてのヒントとして、次の点を考慮してください(Gtk + By Example):

セルデータ関数は、その(レンダラー)列のセルがレンダリングされるたびに呼び出されます。この関数を使用したことがある場合は、プログラムでこの関数が呼び出される頻度を確認してください。セルデータ関数内で時間のかかる操作を行う場合、特に行が多い場合は、処理が速くなりません。

于 2014-04-30T14:47:48.860 に答える