Allerdings hakt es bereits bei der Datenbankprogrammierung mit sqlite3.
Aktuelles Problem ist, dass ich über die grafische Oberfläche eine Änderung eines einzelnen, bestimmten Datensatzes nicht in die Datenbank geschrieben bekomme. Die Änderung an der (parallel) angezeigten Tabelle (=Treeview =Baumansicht) funktioniert jedoch.
Hier ist der Code der Aktionen etc. (Datei: tnote.py):
Code: Alles auswählen
#!/usr/bin/env python
#-*- coding: utf-8-*-
from gi.repository import Gtk
import random, sqlite3
# Erstellung der Datenbankdatei mit einer Tabelle mit zwei Spalten "vorname" und "nachname"
con = sqlite3.connect('testdb1.db')
con.isolation_level = None
cur=con.cursor()
con.execute("CREATE TABLE IF NOT EXISTS schueler (vorname TEXT, nachname TEXT)")
def add_cell_renderer(control, col_no=0, renderer=None, attr='text'):
if renderer is None:
renderer=Gtk.CellRendererText()
control.pack_start(renderer, True)
control.add_attribute(renderer, attr, col_no)
def create_treeview_column(widget, title, col_no, renderer=None, attr='text'):
column = Gtk.TreeViewColumn(title)
widget.append_column(column)
add_cell_renderer(column, col_no, renderer, attr)
def set_entry_completion(entry, completion, col_no, renderer=None):
add_cell_renderer(completion, col_no, renderer)
entry.set_completion(completion)
class TnoteWindow(object):
def __init__(self):
self.builder = Gtk.Builder()
self.builder.add_from_file("tnote.ui")
self.builder.connect_signals(self)
#Daten der Datenbank werden ausgelesen und in Tabelle (=TreeView =Baumansicht) angezeigt
rows = con.execute("SELECT * FROM schueler")
for row in rows:
self.obj('ls_kdaten').append((row[0], row[1]))
## Erzeuge Spalten für Tabelle (=TreeView =Baumansicht) in Grafikmodus
create_treeview_column(self.obj('tv_kdaten'), 'Vorname', 0,
Gtk.CellRendererSpin())
create_treeview_column(self.obj('tv_kdaten'), 'Nachname', 1,
Gtk.CellRendererText())
## Erstes Element der Liste auswählen
self.obj('tv_kdaten').set_cursor(0)
def obj(self, name):
"""
Gibt Glade-Object 'name' zurück
"""
return self.builder.get_object(name)
def run(self):
"""
Startet die zentrale Warteschleife von Gtk
"""
try:
Gtk.main()
except KeyboardInterrupt:
pass
def quit(self):
"""
Verlässt die zentrale Warteschleife von Gtk
"""
Gtk.main_quit()
def get_values(self):
"""
Gibt die Werte aus den Eingabe-Elementen zurück
"""
vorname = self.obj('e_vorname').get_text()
nachname = self.obj('e_nachname').get_text()
return vorname, nachname
def set_values(self, values):
"""
Setzt die Werte der Eingabe-Elemente
"""
self.obj('e_vorname').set_text(values[0])
self.obj('e_nachname').set_text(values[1])
def remove_from_list(self, path):
"""
Entfernt das Elemente mit Pfad 'pfad' aus der Liste
"""
it = self.obj('ls_kdaten').get_iter(path)
self.obj('ls_kdaten').remove(it)
print path, len(self.obj('ls_kdaten'))
if not self.obj('ls_kdaten').iter_is_valid(it):
if path[0] > len(self.obj('ls_kdaten')):
path=(path[0]-1,)
else:
self.set_values(('',''))
self.obj('tv_kdaten').set_cursor(path)
###############################
## Signal-Behandlungsroutinen
###############################
#################
## Hauptfenster
def on_window1_delete_event(self, *args):
self.quit()
#############
## Aktionen
def on_ac_quit_activate(self, action, *args):
self.quit()
def on_ac_neu_activate(self, action, *args):
cur.execute("insert into schueler(vorname, nachname) VALUES('Vorname','Nachname')")
self.obj('ls_kdaten').append(('Vorname', 'Nachname'))
self.obj('tv_kdaten').set_cursor(len(self.obj('ls_kdaten'))-1)
def on_ac_speichern_activate(self, action, *args):
# Problembereich: Aus der angezeigten Tabelle (=TreeView =Baumansicht) und aus der Datenbank sollen zugleich ein einzelner, ausgewählter Datensatz (siehe 'def set_values') geändert werden
vorname = self.builder.get_object('e_vorname').get_text()
nachname = self.builder.get_object('e_nachname').get_text()
# cur.execute("update schueler set vorname=?,nachname=? where id=?", (vorname,nachname))
path = self.obj('tv_kdaten').get_cursor()[0]
if path is not None:
self.obj('ls_kdaten')[path] = self.get_values()
def on_ac_loeschen_activate(self, action, *args):
# wird später weiterentwickelt und soll dann aus der angezeigten Tabelle (=TreeView =Baumansicht) und der Datenbank ein einzelner, ausgewählter Datensatz (siehe 'def set_values') gelöscht werden
path = self.obj('tv_kdaten').get_cursor()[0]
if path is not None:
self.remove_from_list(path)
con.execute("delete from schueler").rowcount, "rows"
def on_tv_kdaten_cursor_changed(self, action, *args):
path = self.obj('tv_kdaten').get_cursor()[0]
if path is not None:
row = self.obj('ls_kdaten')[path]
self.set_values(row)
if __name__ == '__main__':
app = TnoteWindow()
app.run()
Code: Alles auswählen
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<requires lib="gtk+" version="2.16"/>
<!-- interface-naming-policy project-wide -->
<object class="GtkAction" id="ac_loeschen">
<property name="stock_id">gtk-delete</property>
<signal name="activate" handler="on_ac_loeschen_activate" swapped="no"/>
</object>
<object class="GtkAction" id="ac_neu">
<property name="stock_id">gtk-new</property>
<signal name="activate" handler="on_ac_neu_activate" swapped="no"/>
</object>
<object class="GtkAction" id="ac_quit">
<property name="stock_id">gtk-quit</property>
<signal name="activate" handler="on_ac_quit_activate" swapped="no"/>
</object>
<object class="GtkAction" id="ac_speichern">
<property name="stock_id">gtk-save</property>
<signal name="activate" handler="on_ac_speichern_activate" swapped="no"/>
</object>
<object class="GtkAdjustment" id="adjustment1">
<property name="upper">100</property>
<property name="step_increment">1</property>
<property name="page_increment">10</property>
</object>
<object class="GtkEntryCompletion" id="ec_text">
<property name="text_column">2</property>
<property name="inline_completion">True</property>
</object>
<object class="GtkListStore" id="ls_kdaten">
<columns>
<!-- column-name Vorname -->
<column type="gchararray"/>
<!-- column-name Nachname -->
<column type="gchararray"/>
</columns>
</object>
<object class="GtkListStore" id="ls_farben">
<columns>
<!-- column-name Farbe -->
<column type="gchararray"/>
</columns>
</object>
<object class="GtkListStore" id="ls_text"/>
<object class="GtkWindow" id="window1">
<property name="width_request">500</property>
<property name="height_request">500</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="role">Listen-Demo</property>
<signal name="delete-event" handler="on_window1_delete_event" swapped="no"/>
<child>
<object class="GtkVBox" id="vbox1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkMenuBar" id="menubar1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkMenuItem" id="menuitem1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="use_action_appearance">False</property>
<property name="label" translatable="yes">_Datei</property>
<property name="use_underline">True</property>
<child type="submenu">
<object class="GtkMenu" id="menu1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkImageMenuItem" id="imagemenuitem5">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="related_action">ac_quit</property>
<property name="use_underline">True</property>
<property name="use_stock">True</property>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkHBox" id="hbox1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkScrolledWindow" id="scrolledwindow1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hscrollbar_policy">automatic</property>
<property name="vscrollbar_policy">automatic</property>
<property name="shadow_type">etched-in</property>
<child>
<object class="GtkTreeView" id="tv_kdaten">
<property name="width_request">200</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="model">ls_kdaten</property>
<property name="rules_hint">True</property>
<property name="search_column">2</property>
<signal name="cursor-changed" handler="on_tv_kdaten_cursor_changed" swapped="no"/>
</object>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkTable" id="table1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="border_width">30</property>
<property name="n_rows">4</property>
<property name="n_columns">2</property>
<child>
<object class="GtkLabel" id="label3">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Nachname</property>
<property name="use_underline">True</property>
</object>
<packing>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<object class="GtkEntry" id="e_nachname">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="invisible_char">•</property>
<property name="primary_icon_activatable">False</property>
<property name="secondary_icon_activatable">False</property>
<property name="primary_icon_sensitive">True</property>
<property name="secondary_icon_sensitive">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<object class="GtkHButtonBox" id="hbuttonbox1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="spacing">5</property>
<property name="layout_style">spread</property>
<child>
<object class="GtkButton" id="bt_neu">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="related_action">ac_neu</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="bt_speichern">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="related_action">ac_speichern</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkButton" id="bt_loeschen">
<property name="label" translatable="yes">_Löschen</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="related_action">ac_loeschen</property>
<property name="use_underline">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">2</property>
</packing>
</child>
</object>
<packing>
<property name="right_attach">2</property>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
<property name="y_padding">5</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Vorname</property>
<property name="use_underline">True</property>
</object>
<packing>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label4">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">label</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">label</property>
</object>
</child>
<child>
<object class="GtkEntry" id="e_vorname">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="invisible_char">•</property>
<property name="primary_icon_activatable">False</property>
<property name="secondary_icon_activatable">False</property>
<property name="primary_icon_sensitive">True</property>
<property name="secondary_icon_sensitive">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
</packing>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
</object>
</interface>