NoN: progress

Knights of Ni - progress

As said before I am currently working on a GUI for Nikola doing some progress:

  • removed titlebar, using headerbar instead
  • switch between multiple Nikola instances
  • bookmark local Nikola instances (only adding for now)
  • support for multilinual sites:
    • display of configured languages
    • show existent translations in posts/pages tab
    • "Translation" tab: show files, generate new translation file for post/page (this is somehow redundant to the posts/pages tab, I still think about it...)
  • if there is no title the "Title" column will show the slug or (if this does not exist neither) filename
  • some mor log messages to pretent important things happen

Translating articles

As soon as I figured out multilinguality in Nikola I will translate the tutorial series into English.


Well, that was kinda easy...(but I will need some time for translation and writing new stuff and improving the new project).

YouNiversity: Python Tricks

Daniel Bader zeigt auf seinem YouTube-Kanal allerlei Nützliches zum Thema Python.

Aktuell gibt es sein in Arbeit befindliches Buch "Python Tricks. The Book" gerade zum unschlagbaren Preis von 9 $ (+ 1,71 $ deutsche Umsatzsteuer): Klick

Es bestehen keine persönlichen oder/und finanziellen Verbindungen.


Handle dialogue windows

Dialogues are complementary windows which are useful in interaction with the user, to show some relevant information or demand input. The GtkDialog class provides subclasses for common dialogue use cases like the AboutDialog and MessageDialog used in the example file. (FileChooserDialog article).



In the widget sidebar dialog widgets are integrated to the "Toplevel" section next to window widgets.

Dialogs are complementary windows to grab the user's focus. They can fixed to a superordinated window but at least be configured transient to a parent window via General > Window Attributes Transient For:".


The "About" dialog window in general gives information about the project, its version, license, participating programmers, translators etc. All this can be directly typed into Glade.


The MessageDialog is a standard dialog to show information or call for input. It is configurated to be drawn without window decoration or showing up seperately in the taskbar. Furthermore there is the possibility to add standard buttons.

Buttons and responses

Dialogs already own an intern GtkButtonBox to place any buttons in.

In constrast to regular windows the clicked signals of the buttons do not have to be assigned in these Buttonboxes (it's still possible to do so, of course). Instead in the "General" button properties you define a response answer (int) and assign the response signal of the GtkDialog.

Standard buttons available for example in MessageDialogs have a fixed response (see also Python GI API Reference):

  • Ok -5
  • Abort -6
  • Close -7
  • Yes -8
  • No -9
  • [X] -4

The huge advantage of that procedure is that the response refers to the dialog object so the responses can be processed by a single function.

Reestablish dialogues

The problem of windows closed via destroy signal is that they cannot be reactivated therefore the delete-event signal is used here.



When emitting the response signal the response is passed as parameter. As said before this offers the option to process all responses in one function:

def on_dialog_response(self,widget,response):
    if response == 0:
    elif response == 1:
    elif response == (2 or 3):


The hide_on_delete() function removes a window but can be reestablished by show_all():

def on_dialog_delete_event(self,widget,event):
    return True

Several Glade files

As mentioned before several Glade files can be used within a project. It is not possible though to associate dialogs with their parent window if separated into different files. So the set_transient_for function of GtkWindow is required:


Read more…

Data view

Display TreeStore data

(Continuation of the ListStore article)


TreeStore vs. ListStore

In contrast to ListStores TreeStore rows can possess child rows. That's why the append function requires another parameter that specifies the parent row reference:

#append row to liststore

#append row to treestore

The parent value is either

  • None if the current row is not a child row of another, or
  • TreeIter pointing to the superordinate row.

The TreeIter value is generated when creating a row, subordinate rows are created by

row1 = store.append(None,[value1,value2,value3])
row2 = store.append(row1,[value1,value2,value3])

The TreeIter of a cell is obtained by calling the get_selection function of the automatically generated GtkTreeSelection widget.


In the example there are two TreeStores with some columns and the coresponding TreeView widgets to display the data columns.


Sorting a column is set by calling set_sort_column_id. If this is applied to the TreeStore all TreeView widgets using this store are equally sorted.

If this behaviour is not diesired TreeModelSort elements come into play and which are "interposed" between store and view widgets. First the TreeModelSort is created via "Miscellaneous > Tree Model Sort" from the widget sidebar. Then you choose a source TreeView to use data from. After that the model in the TreeView widget is replaced by the newly created TreeModelSort.

The sort function is now simply applied to the TreeModelSort object instead to the TreeView object.


TreeModelFilter allows to only show data that matches the specified filter criteria. Handling this object is analogue to TreeModelSort.

In the example the varieties can be filtered according to fruit colour so there is a GtkButtonBox required to put the corresponding buttons into.

Load formatting values from the model

Besides the columns containing displayed data there is a "weight" column in the first TreeStore. This value is used to show the cell in bold text. It is realized by setting the CellRenderer's property of "Font weight" to the column containing the corresponding value (normal font is 400). In this way the appearance of cells can be defined, for example colours or font formating.



Requesting a position by calling GtkTreeSelection.get_selected() returns a tuple (model, pos), pos of model points to TreeModelSort (or TreeModelFilter) and requires conversion to the TreeStore position:

model,pos = selection.get_selected()
converted_iter = treesort.convert_iter_to_child_iter(pos)


First of all a filter function is required defining the visibility of cells, in the example it's the variable self.color:

def color_filter_func(self,model,iter,data):
    if model[iter][2] == self.color:
        return True
        return False

This function has to be assigned to TreeFilter


A filter process is then executed by calling the refilter() function on the TreeFilter object:

def on_button_clicked(self,widget):
    x.color = widget.get_label()

Read more…