Previous Up Next Tutorial

Quick Start (pyGTK)

The twain module can only be used in an application with a message loop. This section describes how to use the module in a pyGTK application.

The following source code demonstrates a simple application, which retrieves images from the scanner (or other image source), and displays the images in the form. This program is called simple_gtk.py and is in the demo directory of the distribution.

To connect to the data source, select Twain->Open Scanner from the menu. The source manager should give a list of the available data sources. To acquire an image, select Twain->Acquire from the menu.


Example : simple_wx.py

"""simple_gtk.py

This is a simple demonstration of the twain module using pyGTK.

This version does not use callbacks. Instead, it polls to check to
see if the image is ready.
"""

import pygtk
pygtk.require('2.0')
import gtk
import gobject

from simple_base import TwainBase

# You can either Poll the TWAIN source, or process the scanned image in an
# event callback. The event callback has not been fully tested using GTK.
# Specifically this does not work with Tkinter.
USE_CALLBACK=True


class ApplicationWindow(TwainBase):

    ui = '''<ui>
    <menubar name="MenuBar">
      <menu action="TWAIN">
        <menuitem action="Open Scanner"/>
        <menuitem action="Acquire By File"/>
        <menuitem action="Acquire Natively"/>
        <menuitem action="Quit"/>
      </menu>
    </menubar>
    </ui>'''


    def mnuOpenScanner(self, widget=None, event=None, data=None):
        """Connect to the scanner"""
        self.OpenScanner(self.window.window.handle,
            ProductName="Simple pyGTK Demo", UseCallback=USE_CALLBACK)
        return True
    
    def mnuAcquireNatively(self, widget=None, event=None, data=None):
        """Acquire Natively - this is a memory based transfer"""
        return self.AcquireNatively()

    def mnuAcquireByFile(self, widget=None, event=None, data=None):
        """Acquire by file"""
        return self.AcquireByFile()

    def onIdleTimer(self):
        """This is a polling mechanism. Get the image without relying on the callback."""
        self.PollForImage()
        return True

    def DisplayImage(self, ImageFileName):
        """Display the image from a file"""
        self.image.set_from_file(ImageFileName)
        self.image.show()

    def mnuQuit(self, widget=None, event=None, data=None):
        """I want an exit option on the menu. However, I don't know how to do it."""
        return gtk.main_quit()

    def LogMessage(self, title):
        """ Display the title in the window. I use this as a trivial
        trace of the current state of the program"""
        self.window.set_title(title)
        
    def OnQuit(self, event):
        gtk.main_quit()
        
    def __init__(self):
 
        """This is the pyGTK stuff to create the window and menubar"""
 
        # Set up Window
        window = self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
        window.set_size_request(500, 500)
        window.connect("destroy", lambda w: gtk.main_quit())
        self.LogMessage("Twain Demo - pyGTK")
 
        # Set up Widget Container
        vbox = gtk.VBox(False, 0)
        window.add(vbox)
        vbox.show()
      
        # Setup the UI Manager for Menu    
        ui_manager = gtk.UIManager()
        
        # Add Accelerator Group
        accel_group = ui_manager.get_accel_group()
        window.add_accel_group(accel_group)
        
        # Add ActionGroup
        action_group = gtk.ActionGroup('Simple_GTK Actiongroup')
        
        # Create Actions
        action_group.add_actions(
            [
                 ("TWAIN",                None,    "TWAIN",                "T",   None,    None),
                 ("Open Scanner",         None,    "Open Scanner",         "O",   None,    self.mnuOpenScanner),
                 ("Acquire By File",      None,    "Acquire By File",      "F",   None,    self.mnuAcquireByFile),
                 ("Acquire Natively",     None,    "Acquire Natively",     "N",   None,    self.mnuAcquireNatively),
                 ("Quit",                 None,    "Quit",                 "Q",   None,    self.OnQuit)
            ]
        )  
        
        # Attach the ActionGroup
        ui_manager.insert_action_group(action_group, 0)

        # Add a UI Description
        ui_manager.add_ui_from_string(self.ui)

        # Create a menu-bar to hold the menus and add it to our main window
        menubar = ui_manager.get_widget('/MenuBar')
        vbox.pack_start(menubar, False, False, 2)
        menubar.show()

        # Add an Image field to display what is scanned
        self.image = gtk.Image()
        vbox.pack_end(self.image, True, True, 2)
 
        # Display
        window.show()

        # Set up the idle timer. I use this to check to see if an image is ready.
        if not USE_CALLBACK:
            self.idleTimer = gobject.idle_add(self.onIdleTimer)
        

if __name__ == "__main__":
    app = ApplicationWindow()
    gtk.main()


Step 1 - MnuOpenScanner

The MnuOpenScanner calls the TwainBase OpenScanner method. The parameters are the windows handle for the main window, the name of this application and a flag to indicate whether we are using callbacks are polling.

The TWAIN protocol uses the client's windows message queue to perform communication. To access the message queue, the clients window handle is always passed to the SourceManager constructor. The window handle is retrieved using the pyGTK window.window.handle attribute.

Step 2 - MnuAcquireNatively, MnuAcquireByFile

When the client application wants to acquire a document from the scanner, it makes a request to the scanner to acquire the document. There are two transfer mechanisms, transfer by file or transfer natively.

There are implementation problems with some scanners which may make one of the mechanisms inoperable or unreliable.

Step 3 - DisplayImage

This is a simple method to display the image on the screen. The base class ProcessXfer method has done all of the heavy lifting.

Step 4 - MnuQuit

The TWAIN software interfaces to your window message queue. If you close your window without deleting the Source Manager object, the TWAIN software may attempt to write messages to a deleted queue. This may cause your program to hang when it attempts to exit.


Previous Up Next Tutorial