Quizprogramm mit GTK

Code-Stücke können hier veröffentlicht werden.
Antworten
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Da das ja öfter kommt, poste ich mal ein simples Quizprogramm, dass GTK+ benutzt. Es nutzt Glade, weil ich einfach mal gucken wollte wie schwer das geht. Eigentlich ist es relativ einfach, wenn man sich damit 10 Minuten lang beschäftigt. In diesem Programm gibt es zumindest bei mir noch einige Bugs aber das liegt vermutlich daran, dass ich es aus einem Impuls heraus geschrieben habe. Es lässt sich sicher noch optimieren und dazu fordere ich alle auf, die Lust haben.

Code: Alles auswählen

#!/usr/bin/env python 
# -*- Encoding: latin-1 -*-
import gtk
import gtk.glade
from random import randint

data = [
["Was ist 1+1?", "2", "7", "11", "41", 1],
["Was ist 4**4?", "44", "16", "77", "100", 2],
]
answer = 0
qestnum = 0

ui = gtk.glade.XML("quiz.glade")
quest = ui.get_widget("question")
ans1 = ui.get_widget("ans1")
ans2 = ui.get_widget("ans2")
ans3 = ui.get_widget("ans3")
ans4 = ui.get_widget("ans4")

def delete_event(widget, event):
    """The program is finishing"""
    gtk.main_quit()
    return False

def validate(userans):
    quizwin = ui.get_widget("quizwin")
    if userans == answer:
        msg = gtk.MessageDialog(quizwin, 
                    gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
                    gtk.MESSAGE_INFO, gtk.BUTTONS_OK, 
                    "Right!")
        msg.run()
        msg.destroy()
    else: 
        msg = gtk.MessageDialog(quizwin, 
                    gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
                    gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, 
                    "Wrong!")
        msg.run()
        msg.destroy()
    nextquest()

def getrandomquest():
    """Get some random question out of the possible ones"""
    questions = len(data)
    return randint(0, questions - 1)

def nextquest():
    """Go to the next question"""
    qnum = getrandomquest()
    currquest = data[qnum]
    q = currquest[0]
    rightans = currquest[-1]
    global answer
    answer = rightans
    global questnum
    questnum = q
    
    mod_texts(q, currquest[1], currquest[2], currquest[3], currquest[4])

def mod_texts(q, answ1, answ2, answ3, answ4):
    """Set the answers on the buttons"""
    quest.set_text(q)
    ans1.set_label(answ1)
    ans2.set_label(answ2)
    ans3.set_label(answ3)
    ans4.set_label(answ4)
    

def ans_clicked(widget):
    """The event handler for the four answer buttons"""
    answer = widget.get_name()
    if answer == 'ans1':
        validate(1)
    elif answer == 'ans2':
        validate(2)
    elif answer == 'ans3':
        validate(3)
    elif answer == 'ans4':
        validate(4)

signals = {"on_quizwin_delete_event": delete_event,
    "on_ans1_clicked": ans_clicked, "on_ans2_clicked": ans_clicked,
    "on_ans3_clicked": ans_clicked, "on_ans4_clicked": ans_clicked}
ui.signal_autoconnect(signals)

if __name__ == '__main__':
    nextquest()
    gtk.main()
Damit es auch mehr Lerninhalt hat, nutzt es für die UI libglade. Hier die quiz.glade Datei, damit es überhaupt eine UI gibt:

Code: Alles auswählen

<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">

<glade-interface>

<widget class="GtkWindow" id="quizwin">
  <property name="visible">True</property>
  <property name="title" translatable="yes">Das Quiz</property>
  <property name="type">GTK_WINDOW_TOPLEVEL</property>
  <property name="window_position">GTK_WIN_POS_NONE</property>
  <property name="modal">False</property>
  <property name="resizable">False</property>
  <property name="destroy_with_parent">False</property>
  <property name="decorated">True</property>
  <property name="skip_taskbar_hint">False</property>
  <property name="skip_pager_hint">False</property>
  <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
  <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
  <signal name="delete_event" handler="on_quizwin_delete_event" last_modification_time="Wed, 15 Dec 2004 14:51:11 GMT"/>

  <child>
    <widget class="GtkVBox" id="vbox1">
      <property name="visible">True</property>
      <property name="homogeneous">False</property>
      <property name="spacing">0</property>

      <child>
	<widget class="GtkLabel" id="question">
	  <property name="visible">True</property>
	  <property name="label" translatable="yes"></property>
	  <property name="use_underline">False</property>
	  <property name="use_markup">False</property>
	  <property name="justify">GTK_JUSTIFY_LEFT</property>
	  <property name="wrap">False</property>
	  <property name="selectable">False</property>
	  <property name="xalign">0.5</property>
	  <property name="yalign">0.5</property>
	  <property name="xpad">0</property>
	  <property name="ypad">0</property>
	</widget>
	<packing>
	  <property name="padding">0</property>
	  <property name="expand">False</property>
	  <property name="fill">False</property>
	</packing>
      </child>

      <child>
	<widget class="GtkHBox" id="hbox1">
	  <property name="visible">True</property>
	  <property name="homogeneous">False</property>
	  <property name="spacing">0</property>

	  <child>
	    <widget class="GtkButton" id="ans1">
	      <property name="visible">True</property>
	      <property name="can_focus">True</property>
	      <property name="label" translatable="yes">Antwort 1</property>
	      <property name="use_underline">True</property>
	      <property name="relief">GTK_RELIEF_NORMAL</property>
	      <property name="focus_on_click">True</property>
	      <signal name="clicked" handler="on_ans1_clicked" last_modification_time="Wed, 15 Dec 2004 14:55:18 GMT"/>
	    </widget>
	    <packing>
	      <property name="padding">0</property>
	      <property name="expand">False</property>
	      <property name="fill">False</property>
	    </packing>
	  </child>

	  <child>
	    <widget class="GtkButton" id="ans2">
	      <property name="visible">True</property>
	      <property name="can_focus">True</property>
	      <property name="label" translatable="yes">Antwort 2</property>
	      <property name="use_underline">True</property>
	      <property name="relief">GTK_RELIEF_NORMAL</property>
	      <property name="focus_on_click">True</property>
	      <signal name="clicked" handler="on_ans2_clicked" last_modification_time="Wed, 15 Dec 2004 14:55:24 GMT"/>
	    </widget>
	    <packing>
	      <property name="padding">0</property>
	      <property name="expand">False</property>
	      <property name="fill">False</property>
	    </packing>
	  </child>

	  <child>
	    <widget class="GtkButton" id="ans3">
	      <property name="visible">True</property>
	      <property name="can_focus">True</property>
	      <property name="label" translatable="yes">Antwort 3</property>
	      <property name="use_underline">True</property>
	      <property name="relief">GTK_RELIEF_NORMAL</property>
	      <property name="focus_on_click">True</property>
	      <signal name="clicked" handler="on_ans3_clicked" last_modification_time="Wed, 15 Dec 2004 14:55:29 GMT"/>
	    </widget>
	    <packing>
	      <property name="padding">0</property>
	      <property name="expand">False</property>
	      <property name="fill">False</property>
	    </packing>
	  </child>

	  <child>
	    <widget class="GtkButton" id="ans4">
	      <property name="visible">True</property>
	      <property name="can_focus">True</property>
	      <property name="label" translatable="yes">Antwort 4</property>
	      <property name="use_underline">True</property>
	      <property name="relief">GTK_RELIEF_NORMAL</property>
	      <property name="focus_on_click">True</property>
	      <signal name="clicked" handler="on_ans4_clicked" last_modification_time="Wed, 15 Dec 2004 14:55:34 GMT"/>
	    </widget>
	    <packing>
	      <property name="padding">0</property>
	      <property name="expand">False</property>
	      <property name="fill">False</property>
	    </packing>
	  </child>
	</widget>
	<packing>
	  <property name="padding">0</property>
	  <property name="expand">True</property>
	  <property name="fill">True</property>
	</packing>
      </child>
    </widget>
  </child>
</widget>

</glade-interface>
Viel Spaß beim raten!
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Antworten