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.
"""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.