CVS: anygui/lib/anygui/backends gtkgui.py,1.24,1.25 qtgui.py,1.21,1.22
"Dallas T. Johnston" <[email protected]> Fri, 08 Nov 2002 02:52:25 -0800
| Newsgroups | gmane.comp.python.anygui.cvs |
|---|---|
| Message-ID | <[email protected]> |
Update of /cvsroot/anygui/anygui/lib/anygui/backends In directory usw-pr-cvs1:/tmp/cvs-serv32337/lib/anygui/backends Modified Files: gtkgui.py qtgui.py Log Message: Finally got SF to accept the commit... =) Index: gtkgui.py =================================================================== RCS file: /cvsroot/anygui/anygui/lib/anygui/backends/gtkgui.py,v retrieving revision 1.24 retrieving revision 1.25 diff -C2 -r1.24 -r1.25 *** gtkgui.py 26 Oct 2002 16:22:03 -0000 1.24 --- gtkgui.py 8 Nov 2002 10:52:23 -0000 1.25 *************** *** 1,35 **** - """ - skelgui.py is an empty skeleton waiting for you to implement an - Anygui back-end. - - You should probably read IRFC14 (nondist/irfc/irfc-0014.txt - in the CVS repository) before trying to implement an - Anygui backend. Specifically, you should understand the - terms "proxy", "wrapper", and "(native) widget" as - they're used in Anygui. The classes implemented in - a backend (and the classes in this file) are "wrappers" - around "native widgets". - - To use this skeleton, simply copy it to a file in the - anygui/lib/backends directory called <yourbackend>gui.py, - and implement all of the methods and event handlers - described below. Depending on your particular backend, there - may be some opportunities to combine methods into mixin classes. - - The fastest way to resolve any questions or ambiguities - about this file, is to look at one of the existing - back-end implementations in the anygui/lib/anygui/backends - directory. Failing that, post your question to - the Anygui development list ([email protected]). - - If you are implementing an Anygui backend, you should - be subscribed to the development list. See - - http://lists.sourceforge.net/lists/listinfo/anygui-devel - - for subscription instructions. - - Comments and criticism to [email protected] (Joe Knapka). - """ try: # Import Anygui infrastructure. You shouldn't have to change these. --- 1,2 ---- *************** *** 70,98 **** class ComponentWrapper(AbstractWrapper): - """ - The ComponentWrapper class should abstract away all behavior - that (nearly) all backend widgets perform similarly. Normally, - this will include geometry and visibility management, and in some - cases widget creation can be handled here as well (see wxgui.py - for example). - """ def __init__(self, *args, **kwds): ! """ ! Common widget wrapper initialization code. The main thing that ! we would normally do here is set any backend-specific ! attribute constraints. ! ! Whenever the application code alters a widget proxy, the front end ! will "push" any changed widget attributes into the backend by ! calling the wrapper.set<Attribute>(self,new_value) method for any ! attribute that changes. The setContraints() method allows the ! backend to specify the order in which the set<Attribute>() ! method calls are made, by specifying the order in which attribute ! names are set. The constraints set here are just examples. ! However, it is almost certainly a good idea to ensure that ! 'container' is set before any other attribute, so at minimum ! you should call "self.setConstraints('container')" here. ! """ AbstractWrapper.__init__(self, *args, **kwds) --- 37,43 ---- class ComponentWrapper(AbstractWrapper): def __init__(self, *args, **kwds): ! AbstractWrapper.__init__(self, *args, **kwds) *************** *** 107,190 **** def widgetFactory(self,*args,**kws): - """ Create and return the backend widget for this wrapper. For - example, mswgui.py uses the win32gui.CreateWindowEx() call - here to create a Windows native widget. The value returned - will be immediately assigned to self.widget by the Anygui - framework; henceforth you should refer to self.widget. """ raise NotImplementedError, 'should be implemented by subclasses' def enterMainLoop(self): # ... - """ enterMainLoop() is called when the application event loop is - started for the first time. """ if not self.widget: return self.widget.show() def destroy(self): - """ - destroy() is called when the application needs to destroy the - native widget. You can also call it within the wrapper code if - you need to destroy your native widget for some reason. You - should set self.widget to DummyWidget() - here, after destroying the native widget. - """ if self.widget: self.widget.destroy() self.widget = None ! # From here on, all methods in this class are getters and setters. ! # Setters must be implemented; they are called automatically in ! # response to application-code manipulation of the associated ! # proxy object, and perform the required magic on self.widget ! # to implement the change. ! # ! # Getters need not be implemented unless the backend requires ! # special handling, or if the attribute in question can be changed ! # by user actions as well as by application code. Getters are ! # called automatically during proxy attribute access, if they ! # exist; otherwise the last value set in the proxy is returned. ! # This file provides empty getter definitions for those attributes ! # that will nearly always require special handling for get ! # operations. ! # ! # The setters and getters here are a typical example of ! # attribute handling that's common to all of a backend's ! # widgets. For example, getGeometry() and setGeometry() work ! # the same for any backend widget, thus they're included ! # here in the common wrapper base class. ! # ! # Note that you must implement all the setter and getter ! # methods in this file in order for your backend to work ! # properly! ! def setContainer(self,container): - """ - setContainer() is called whenever the proxy's container (the - Frame or top-level Window) in which the widget will appear is - set. It's called implicitly when a widget is added to a - container via the container.add(widget) method. - - In most backends, you'll call self.create() here in order to - actually create the backend widget. create() is a template - method that calls self.widgetFactory() to create the widget, - and then performs some bookkeeping for the wrapper. - - When the widget is removed from its container, setContainer() - will be called with container==None; you must handle that case - correctly, whatever that means for your backend. - """ if container is None: - # Handle "removed from container" case. self.destroy() return ! parent = container ! self.create(parent) ! self.proxy.push(blocked=['container']) def setGeometry(self,x,y,width,height): - """ Set the native widget's geometry. Note that we call - self.noWidget() here to see if the wrapper has a native widget - to manage. You should probably use this idiom at the start of - all setter and getter methods, unless you have a very good - reason not to. """ if not self.widget: return self.widget.set_uposition(int(x), int(y)) --- 52,78 ---- def widgetFactory(self,*args,**kws): raise NotImplementedError, 'should be implemented by subclasses' def enterMainLoop(self): # ... if not self.widget: return self.widget.show() def destroy(self): if self.widget: self.widget.destroy() self.widget = None ! # getters and setters def setContainer(self,container): if container is None: self.destroy() return ! parent = container.wrapper.widget ! if parent is None: ! self.create(parent) ! self.proxy.push(blocked=['container']) ! self.setupChildWidgets() def setGeometry(self,x,y,width,height): if not self.widget: return self.widget.set_uposition(int(x), int(y)) *************** *** 192,198 **** def getGeometry(self): - """ Get the native widget's geometry as an (x,y,w,h) tuple. - Since the geometry can be changed by the user dragging the - window frame, you must implement this method. """ if not self.widget: return return self.widget.get_uposition(int(x), int(y)) + \ --- 80,83 ---- *************** *** 200,204 **** def setVisible(self,visible): - """ Set/get the native widget's visibility. """ if not self.widget: return if visible: --- 85,88 ---- *************** *** 208,228 **** def setEnabled(self,enabled): - """ Set/get the native widget's enabled/disabled state. """ if not self.widget: return self.widget.set_sensitive(int(enabled)) def setText(self,text): - """ Set/get the text associated with the widget. This might be - window title, frame caption, label text, entry field text, - or whatever. - """ if not self.widget: return raise NotImplementedError, 'should be implemented by subclasses' class LabelWrapper(ComponentWrapper): ! """ ! Wraps a backend "label" widget - static text. ! You may need to implement setText() here. ! """ def widgetFactory(self, *args, **kws): print "In LabelWrapper.widgetFactory()" --- 92,104 ---- def setEnabled(self,enabled): if not self.widget: return self.widget.set_sensitive(int(enabled)) def setText(self,text): if not self.widget: return raise NotImplementedError, 'should be implemented by subclasses' class LabelWrapper(ComponentWrapper): ! def widgetFactory(self, *args, **kws): print "In LabelWrapper.widgetFactory()" *************** *** 245,253 **** class ListBoxWrapper(ComponentWrapper): - """ - Wraps a backend listbox. - At the moment, Anygui supports only single-select mode. - """ connected = 0 --- 121,125 ---- *************** *** 270,274 **** """ if not self.widget: return ! return self.widget._listbox.rows def setSelection(self,selection): --- 142,146 ---- """ if not self.widget: return ! return list(self.widget._listbox.rows) def setSelection(self,selection): *************** *** 288,302 **** def widgetSetUp(self): ! """ ! widgetSetUp() is called by the Anygui framework immediately after ! the native widget has been created and assigned to self.widget. ! The most common use of widgetSetUp() is to register any event ! handlers necessary to deal with user actions. ! ! The ListBox widget requires that an Anygui 'select' event be ! fired whenever the user selects an item of the listbox. ! self._select() sends the event, so here you should associate ! the back-end's selection event with the self._select method. ! """ if not self.connected: self.widget._listbox.connect("select_row", self._select) --- 160,164 ---- def widgetSetUp(self): ! """ Connect ListBox events """ if not self.connected: self.widget._listbox.connect("select_row", self._select) *************** *** 304,314 **** def _select(self,*args): - """ - Send an Anygui 'select' event when the user clicks or otherwise - selects a listbox item. Note that the source of the event is - self.proxy, not self; that's because application code only - knows about proxies, not wrappers, so the source of the Anygui - event must be a proxy. - """ send(self.proxy,'select') --- 166,169 ---- *************** *** 337,340 **** --- 192,196 ---- def setText(self, text): + if not self.widget: return self.widget.children()[0].set_text(str(text)) *************** *** 344,356 **** class ToggleButtonMixin(ButtonWrapper): - """ - Checkboxes and radio buttons often have common behavior that can - be abstracted away; on the other hand, sometimes they don't. - Consider this an example only. - - They also should generate 'click' events, so we'll just inherit - ButtonWrapper here to get the event setup code. Your backend - may not permit this, however; do what needs to be done. - """ def getOn(self): --- 200,203 ---- *************** *** 420,428 **** class TextControlMixin: - """ - Single-line entry fields and multiline text controls usually - have a lot of common behavior that can be abstracted away. Do - that here. - """ def setText(self,text): --- 267,270 ---- Index: qtgui.py =================================================================== RCS file: /cvsroot/anygui/anygui/lib/anygui/backends/qtgui.py,v retrieving revision 1.21 retrieving revision 1.22 diff -C2 -r1.21 -r1.22 *** qtgui.py 24 Sep 2002 15:28:29 -0000 1.21 --- qtgui.py 8 Nov 2002 10:52:23 -0000 1.22 *************** *** 1,4 **** ! from anygui.backends import * ! import sys __all__ = ''' --- 1,25 ---- ! #==============================================================# ! # Imports ! ! try: ! # Anygui specific imports ! from anygui.backends import * ! from anygui.Applications import AbstractApplication ! from anygui.Wrappers import AbstractWrapper ! from anygui.Events import * ! from anygui.Windows import Window ! from anygui import application ! from anygui.Menus import Menu, MenuCommand, MenuCheck, MenuSeparator ! ! # qtgui specific imports ! import sys ! from weakref import ref as wr ! from qt import * ! except: ! import traceback ! traceback.print_exc() ! ! #==============================================================# ! # Exports __all__ = ''' *************** *** 21,34 **** '''.split() - #==============================================================# ! from weakref import ref as wr ! from qt import * ! from anygui.Applications import AbstractApplication ! from anygui.Wrappers import AbstractWrapper ! from anygui.Events import * ! from anygui.Windows import Window ! from anygui import application ! from anygui.Menus import Menu, MenuCommand, MenuCheck, MenuSeparator TRUE = 1 --- 42,47 ---- '''.split() #==============================================================# ! # Local Constants TRUE = 1 *************** *** 39,57 **** #==============================================================# ! ! class Application(AbstractApplication, QApplication): ! ! def __init__(self): ! AbstractApplication.__init__(self) ! QApplication.__init__(self,[]) ! ! def internalRun(self): ! qApp.exec_loop() ! ! def internalRemove(self): ! if not self._windows: ! qApp.quit() ! ! #==============================================================# class Wrapper(AbstractWrapper): --- 52,56 ---- #==============================================================# ! # Factoring out creational code... class Wrapper(AbstractWrapper): *************** *** 83,86 **** --- 82,86 ---- #==============================================================# + # Base class for all Widgets # FIXME: It seems that layout stuff (e.g. hstretch and vmove) is set *************** *** 136,150 **** def setContainer(self, container): if container is None: return - # if container is None: - # try: - # self.destroy() - # except: - # pass - # return parent = container.wrapper.widget try: assert parent is None ! except (AttributeError, AssertionError): ! # self.destroy() self.create(parent) self.proxy.push(blocked=['container']) --- 136,143 ---- def setContainer(self, container): if container is None: return parent = container.wrapper.widget try: assert parent is None ! except (AssertionError): self.create(parent) self.proxy.push(blocked=['container']) *************** *** 170,179 **** return "" - # def setText(self, text): - # try: self.widget - # - # def getText(self): - # return "" - def setupChildWidgets(self): pass --- 163,166 ---- *************** *** 184,187 **** --- 171,180 ---- class EventFilter(QObject): + """ + This class is used as a generic event filter + for Qt based widgets. This is really only a + temp fix for some slight problems with PyQt. + """ + _comp = None _events = {} *************** *** 200,203 **** --- 193,197 ---- #==============================================================# + # Label class LabelWrapper(ComponentWrapper): *************** *** 212,215 **** --- 206,210 ---- #==============================================================# + # ListBox class ListBoxWrapper(ComponentWrapper): *************** *** 254,257 **** --- 249,253 ---- #==============================================================# + # Base class for Button widgets class ButtonWrapperBase(ComponentWrapper): *************** *** 269,273 **** send(self.proxy,'click') ! #--------------------------------------------------------------# class ButtonWrapper(ButtonWrapperBase): --- 265,270 ---- send(self.proxy,'click') ! #==============================================================# ! # Button class ButtonWrapper(ButtonWrapperBase): *************** *** 279,283 **** return QPushButton(*args, **kwds) ! #--------------------------------------------------------------# class ToggleButtonWrapperBase(ButtonWrapperBase): --- 276,281 ---- return QPushButton(*args, **kwds) ! #==============================================================# ! # Base class for Toggle widgets class ToggleButtonWrapperBase(ButtonWrapperBase): *************** *** 294,298 **** return bool(self.widget.isChecked()) ! #--------------------------------------------------------------# class CheckBoxWrapper(ToggleButtonWrapperBase): --- 292,297 ---- return bool(self.widget.isChecked()) ! #==============================================================# ! # CheckBox class CheckBoxWrapper(ToggleButtonWrapperBase): *************** *** 305,309 **** ! #--------------------------------------------------------------# class RadioButtonWrapper(ToggleButtonWrapperBase): --- 304,310 ---- ! ! #==============================================================# ! # RadioButton class RadioButtonWrapper(ToggleButtonWrapperBase): *************** *** 331,340 **** def setValue(self, value): ! self.widget.setChecked(int(value)) def getValue(self): ! return int(self.widget.isChecked()) #==============================================================# class TextWrapperBase(ComponentWrapper): --- 332,342 ---- def setValue(self, value): ! self.widget.setChecked(bool(value)) def getValue(self): ! return bool(self.widget.isChecked()) #==============================================================# + # Base class for Text widgets class TextWrapperBase(ComponentWrapper): *************** *** 362,367 **** def keyPressHandler(self, event): if DEBUG: print 'in keyPressHandler of: ', self.widget ! self.proxy.text = self.widget.text() ! #self.modify(text=self._backend_text()) if int(event.key()) == 0x1004: #Qt Return Key Code send(self, 'enterkey') --- 364,368 ---- def keyPressHandler(self, event): if DEBUG: print 'in keyPressHandler of: ', self.widget ! self.proxy.pull('text') if int(event.key()) == 0x1004: #Qt Return Key Code send(self, 'enterkey') *************** *** 372,394 **** if DEBUG: print 'in gotFocusHandler of: ', self.widget return 1 ! # send(self, 'gotfocus') def lostFocusHandler(self, event): if DEBUG: print 'in lostFocusHandler of: ', self.widget return 1 ! # send(self, 'lostfocus') ! def qtCalcStartEnd(self, text, mtxt, pos): ! start, idx = 0, -1 ! for n in range(text.count(mtxt)): ! idx = text.find(mtxt, idx+1) ! if idx <= pos <= idx + len(mtxt): ! start = idx ! break ! end = start + len(mtxt) ! if DEBUG: print 'returning => start: %s | end: %s' %(start,end) ! return start, end ! #--------------------------------------------------------------# class TextFieldWrapper(TextWrapperBase): --- 373,396 ---- if DEBUG: print 'in gotFocusHandler of: ', self.widget return 1 ! # send(self.proxy, 'gotfocus') def lostFocusHandler(self, event): if DEBUG: print 'in lostFocusHandler of: ', self.widget return 1 ! # send(self.proxy, 'lostfocus') ! # def qtCalcStartEnd(self, text, mtxt, pos): ! # start, idx = 0, -1 ! # for n in range(text.count(mtxt)): ! # idx = text.find(mtxt, idx+1) ! # if idx <= pos <= idx + len(mtxt): ! # start = idx ! # break ! # end = start + len(mtxt) ! # if DEBUG: print 'returning => start: %s | end: %s' %(start,end) ! # return start, end ! #==============================================================# ! # TextField class TextFieldWrapper(TextWrapperBase): *************** *** 415,419 **** return pos, pos ! #--------------------------------------------------------------# class TextAreaWrapper(TextWrapperBase): --- 417,422 ---- return pos, pos ! #==============================================================# ! # TextArea class TextAreaWrapper(TextWrapperBase): *************** *** 427,434 **** def setSelection(self, selection): if DEBUG: print 'in setSelection of: ', self.widget ! start, end = selection ! spara, sidx = self.qtTranslateParaIdx(start) ! epara, eidx = self.qtTranslateParaIdx(end) ! self.widget.setSelection(spara, sidx, epara, eidx) def getSelection(self): --- 430,438 ---- def setSelection(self, selection): if DEBUG: print 'in setSelection of: ', self.widget ! if self.widget is not None: ! start, end = selection ! spara, sidx = self.qtTranslateParaIdx(start) ! epara, eidx = self.qtTranslateParaIdx(end) ! self.widget.setSelection(spara, sidx, epara, eidx) def getSelection(self): *************** *** 450,454 **** if self.widget is not None: for n in range(self.widget.paragraphs()): ! paras.append(str(self.widget.text(n)) + '\n') if DEBUG: print 'paragraphs are: \n' --- 454,458 ---- if self.widget is not None: for n in range(self.widget.paragraphs()): ! paras.append(str(self.widget.text(n))) if DEBUG: print 'paragraphs are: \n' *************** *** 486,489 **** --- 490,494 ---- #==============================================================# + # Frame class FrameWrapper(ComponentWrapper): *************** *** 503,506 **** --- 508,512 ---- #==============================================================# + # Window class WindowWrapper(ComponentWrapper): *************** *** 625,628 **** --- 631,635 ---- #==============================================================# + # GroupBox class GroupBoxWrapper(ComponentWrapper): *************** *** 641,644 **** --- 648,652 ---- #==============================================================# + # Menu class MenuItemMixin: *************** *** 654,669 **** def setEnabled(self,enabled): ! if self.proxy.container is None or self.proxy.container.wrapper.noWidget(): ! return ! self.proxy.container.wrapper.rebuild() def setContainer(self,container): if not container: ! if self.proxy.container is None: ! return ! if self.proxy in self.proxy.container.contents: ! self.proxy.container.contents.remove(self.proxy) ! self.widget = None ! self.proxy.container.wrapper.rebuild() else: self.createIfNeeded() --- 662,676 ---- def setEnabled(self,enabled): ! if self.proxy.container is not None \ ! and self.proxy.container.wrapper.widget is not None: ! self.proxy.container.wrapper.rebuild() def setContainer(self,container): if not container: ! if self.proxy.container is not None: ! if self.proxy in self.proxy.container.contents: ! self.proxy.container.contents.remove(self.proxy) ! self.widget = None ! self.proxy.container.wrapper.rebuild() else: self.createIfNeeded() *************** *** 671,678 **** def setText(self,text): ! if self.proxy.container is None or self.proxy.container.wrapper.noWidget(): ! return ! ! self.proxy.container.wrapper.rebuild() def getText(self): --- 678,684 ---- def setText(self,text): ! if self.proxy.container is not None \ ! and self.proxy.container.wrapper.widget is not None: ! self.proxy.container.wrapper.rebuild() def getText(self): *************** *** 691,707 **** def setContainer(self,container): ! if not container: ! if self.noWidget: ! return ! if self.proxy in self.proxy.container.contents: ! self.proxy.container.contents.remove(self.proxy) ! #print "DESTROYING",self ! self.widget.destroy() ! self.widget = None ! self.proxy.container.wrapper.rebuild() else: ! if container.wrapper.noWidget(): ! return ! self.rebuild() def setContents(self,contents): --- 697,711 ---- def setContainer(self,container): ! if container is None: ! if self.widget is not None: ! if self.proxy in self.proxy.container.contents: ! self.proxy.container.contents.remove(self.proxy) ! #print "DESTROYING",self ! self.widget.destroy() ! self.widget = None ! self.proxy.container.wrapper.rebuild() else: ! if container.wrapper.widget is not None: ! self.rebuild() def setContents(self,contents): *************** *** 712,723 **** Rebuild the entire menu structure starting from the toplevel menu. """ ! if self.proxy.container is None or self.noWidget(): ! return ! if self.proxy.container.wrapper.noWidget(): ! return ! proxies = [self.proxy] ! while not isinstance(proxies[-1],Window): ! proxies.append(proxies[-1].container) ! proxies[-2].wrapper.rebuild() def rebuild(self): --- 716,725 ---- Rebuild the entire menu structure starting from the toplevel menu. """ ! if self.proxy.container is not None and self.widget is not None and \ ! self.proxy.container.wrapper.widget is not None: ! proxies = [self.proxy] ! while not isinstance(proxies[-1],Window): ! proxies.append(proxies[-1].container) ! proxies[-2].wrapper.rebuild() def rebuild(self): *************** *** 726,750 **** self to parent. """ ! if self.proxy.container is None or self.proxy.container.wrapper.noWidget(): ! return ! ! parent = self.proxy.container.wrapper.widget ! if DEBUG: print "\nREBUILDING: ", self,self.proxy.contents ! if self.widget is not None: ! self.widget.clear() ! else: ! if isinstance(self.proxy.container, Window): ! self.create(parent) else: ! self.create(None) ! for item in self.proxy.contents: ! item.wrapper.createIfNeeded() ! item.wrapper.insertInto(self.widget) ! if item.wrapper.itemId != -1: ! self.widget.setItemEnabled(item.wrapper.itemId, item.enabled) def enterMainLoop(self): # ... ! self.proxy.push() # FIXME: Why is this needed when push is called in internalProd (by prod)? def insertInto(self, widget): --- 728,752 ---- self to parent. """ ! if self.proxy.container is not None and \ ! self.proxy.container.wrapper.widget is not None: ! parent = self.proxy.container.wrapper.widget ! if DEBUG: print "\nREBUILDING: ", self,self.proxy.contents ! if self.widget is not None: ! self.widget.clear() else: ! if isinstance(self.proxy.container, Window): ! self.create(parent) ! else: ! self.create(None) ! for item in self.proxy.contents: ! item.wrapper.createIfNeeded() ! item.wrapper.insertInto(self.widget) ! if item.wrapper.itemId != -1: ! self.widget.setItemEnabled(item.wrapper.itemId, item.enabled) def enterMainLoop(self): # ... ! self.proxy.push() # FIXME: Why is this needed when push ! # is called in internalProd (by prod)? def insertInto(self, widget): *************** *** 795,796 **** --- 797,814 ---- widget.insertSeparator() + #==============================================================# + + class Application(AbstractApplication, QApplication): + + def __init__(self): + AbstractApplication.__init__(self) + QApplication.__init__(self,[]) + + def internalRun(self): + qApp.exec_loop() + + def internalRemove(self): + if not self._windows: + qApp.quit() + + #==============================================================# ------------------------------------------------------- This sf.net email is sponsored by: See the NEW Palm Tungsten T handheld. Power & Color in a compact size! http://ads.sourceforge.net/cgi-bin/redirect.pl?palm0001en