Hi,

I am using pygtk for the first times.

I am wondering what would be the best "pattern" to interface pygtk with
a thread.

The thread is collecting informations (over the network for example) or
is doing some long calculations.

I would like also to separate the gui part to the action part so that I
should be easier to maintain.

************************************************************
What should be the best practice in order to achieve this ?
***********************************************************

What I use now is :



1)
the gui is launching the "action" evrey 1 sec and is checking for
message using a queue every second also.

gui.py

....etc ...
class window1(SimpleGladeApp):
[EMAIL PROTECTED] class window1 }
    [EMAIL PROTECTED] init window1.__init__ {
    def __init__(self, path='gui.glade',
                 root='window1',
                 domain=app_name, kwargs={}):
        path = os.path.join(glade_dir, path)
        SimpleGladeApp.__init__(self, path, root, domain, **kwargs)
        self.q=Queue.Queue()
        self.action=act.action(self.q)
        gobject.timeout_add (1000,self.action.go) # this is the action
asked
        gobject.timeout_add (1000,self.process) # check if a new message is
available in the queue

    def process (self):
        dir (self.q)
        if self.q.empty() == False :
                print "from main ",self.q.get()
        return True

 ...etc ....

2)
The action part is making somehow the interface between the running
thread and the gui :
It puts the new information in the queue for the gui to process it
later.


action.py

import os
import gui
import time
import Queue
import Spethread # thread that always run in the background

class Singleton(object):
    _instance = None
    def __new__(cls, *args, **kwargs):
        if not cls._instance:
            cls._instance = super(Singleton, cls).__new__(cls, *args,
**kwargs)
        return cls._instance


class action(Singleton):
    def __init__(self, queue):
        self.q=queue
        self.thread_seb=Spethread.worker()
        self.thread_seb.start()
        self.go()

    def go(self):
        if self.thread_seb:
            reponse=self.thread_seb.status()
            self.q.put(reponse)
        else :
            self.q.put("le thread n'existe plus ")
        return True

    def stop(self):
        self.thread_seb.die()


3)
The thread part is "just" a thread that should from time to time
time.Sleep in order for action to query if it has some new messages.

Spethread.py

import threading
import time

class worker(threading.Thread):

        def __init__(self):
                threading.Thread.__init__(self)
                self.value=0
                self.go_on=1

        def run(self):
                print "self.go_on=",self.go_on
                while self.go_on == 1:
                        self.value=int(time.time())
                        res=2
                        for i in range(0, 100):
                                res=res^i
                                print res
                        time.Sleep(0.01)
        def status(self):
                return self.value


        def die(self):
                print "die request"
                self.go_on=0


Thanks in advance for sharing this informations.
Sebastien.

PS :
the entire gui.py

[EMAIL PROTECTED] python gui.py {
[EMAIL PROTECTED] header gui.py {
#!/usr/bin/env python
# -*- coding: UTF8 -*-

# Python module gui.py
# Autogenerated from gui.glade
# Generated on Wed Sep 20 22:03:00 2006

# Warning: Do not modify any context comment beginning with # @--
# They are required to keep user's code
# Doing so will make it unable for kefir to help you further manage
your project

[EMAIL PROTECTED] header gui.py }
[EMAIL PROTECTED] app gui {
import os
import gobject
import gtk
import action as act
import Queue

from SimpleGladeApp import SimpleGladeApp, bindtextdomain

app_name = 'gui'
app_version = '0.0.1'

glade_dir = ''
locale_dir = ''

bindtextdomain(app_name, locale_dir)

[EMAIL PROTECTED] app gui }
[EMAIL PROTECTED] window window1 {
[EMAIL PROTECTED] class window1 {
class window1(SimpleGladeApp):
[EMAIL PROTECTED] class window1 }
    [EMAIL PROTECTED] init window1.__init__ {
    def __init__(self, path='gui.glade',
                 root='window1',
                 domain=app_name, kwargs={}):
        path = os.path.join(glade_dir, path)
        SimpleGladeApp.__init__(self, path, root, domain, **kwargs)
        self.q=Queue.Queue()
        self.action=act.action(self.q)
        gobject.timeout_add (1000,self.action.go)
        gobject.timeout_add (1000,self.process)
    [EMAIL PROTECTED] init window1.__init__ }
    [EMAIL PROTECTED] new window1.new {
    def new(self):
        print 'A new %s has been created' % self.__class__.__name__
    [EMAIL PROTECTED] new window1.new }
    [EMAIL PROTECTED] custom window1 {
    #   Write your own methods here
    [EMAIL PROTECTED] custom window1 }
    [EMAIL PROTECTED] callback window1.on_button1_clicked {
    def on_button1_clicked(self, widget, args=[]):
        print 'on_button1_clicked called with self.%s' %
widget.get_name()
        self.action.stop()
        print "arrete de thread"
    [EMAIL PROTECTED] callback window1.on_button1_clicked }
    def process (self):
        dir (self.q)
        if self.q.empty() == False :
                print "from main ",self.q.get()
        return True

[EMAIL PROTECTED] window window1 }
[EMAIL PROTECTED] main gui.py {
[EMAIL PROTECTED] init main {
def main():
[EMAIL PROTECTED] init main }
[EMAIL PROTECTED] body main {
    Window1 = window1()
    Window1.run()
[EMAIL PROTECTED] body main }
[EMAIL PROTECTED] main gui.py }
[EMAIL PROTECTED] run gui.py {
if __name__ == '__main__':
    main()
[EMAIL PROTECTED] run gui.py }
[EMAIL PROTECTED] python gui.py }



the glade file:


<?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="window1">
  <property name="visible">True</property>
  <property name="title" translatable="yes">window1</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">True</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>
  <property name="focus_on_map">True</property>
  <property name="urgency_hint">False</property>

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

      <child>
        <widget class="GtkEntry" id="entry1">
          <property name="visible">True</property>
          <property name="can_focus">True</property>
          <property name="editable">True</property>
          <property name="visibility">True</property>
          <property name="max_length">0</property>
          <property name="text" translatable="yes">this is it</property>
          <property name="has_frame">True</property>
          <property name="invisible_char">*</property>
          <property name="activates_default">False</property>
        </widget>
        <packing>
          <property name="padding">0</property>
          <property name="expand">True</property>
          <property name="fill">True</property>
        </packing>
      </child>

      <child>
        <widget class="GtkButton" id="button1">
          <property name="visible">True</property>
          <property name="can_focus">True</property>
          <property name="label" translatable="yes">button1</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_button1_clicked"
last_modification_time="Wed, 20 Sep 2006 19:59:06 GMT"/>
        </widget>
        <packing>
          <property name="padding">0</property>
          <property name="expand">False</property>
          <property name="fill">False</property>
          <property name="pack_type">GTK_PACK_END</property>
        </packing>
      </child>
    </widget>
  </child>
</widget>

</glade-interface>

-- 
http://mail.python.org/mailman/listinfo/python-list

Reply via email to