Anfänger-Problem bei Änderung eines Datensatzes mit sqlite3
Verfasst: Mittwoch 27. Juni 2012, 21:20
Ich bin ein Neuling bezüglich der Programmiersprache python und nutze seit Jahren privat Ubuntu und Fedora. Nach 15 Jahren hat mich wieder die Programmier-Sucht erfasst und ich will ein relativ einfaches Programm schreiben und im Erfolgsfall unter GNU-Lizenz veröffentlichen.
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):
Und hier ist der Code der grafischen Oberfläche (Datei: tnote.ui):
Vielen Dank im Voraus. Zudem suche ich Mitstreiter, die Interesse an der gemeinsamen Programmierung haben. Dabei wäre ich bereits mit einem Ratgeber zufrieden, würde mich aber an aktive Mitprogrammierer freuen. Ziel ist ein Open-Source-Programm für Lehrer, welches den Lehrern die Notenverwaltung und Kommunikation zu den Eltern erleichtert. Ich selbst bin kein Lehrer, sondern Rechtsanwalt uńd will hierdurch Freunde und Lebensgefährtin unterstützen.
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>