On 10/6/07, Phil Thompson <[EMAIL PROTECTED]> wrote: > > On Saturday 06 October 2007, Arve Knudsen wrote: > > On 10/6/07, Phil Thompson <[EMAIL PROTECTED]> wrote: > > > On Friday 05 October 2007, Arve Knudsen wrote: > > > > Hi > > > > I've just written a Designer plugin in Python, which I have to say > is > > > > > > very > > > > > > > nice. However I discovered some surprising behaviour in pyuic. My > > > > widget contains Qt properties (defined using pyqtProperty), but the > > > > generated > > > > > > code > > > > > > > don't use the properties, instead it tries to use the underlying > > > > > > methods!? > > > > > > > I discovered this for the reason that I use a different naming > > > > > > convention > > > > > > > than pyuic apparently expected. For instance, I had a property > "value", > > > > > > for > > > > > > > which pyuic expected there to be a setter method "setValue". I hope > it > > > > isn't on purpose that pyuic tries to use underlying methods instead > of > > > > > > the > > > > > > > properties themselves? > > > > > > > > I'm using PyQt 4.3 commercial edition. > > > > > > > > Thanks, > > > > Arve > > > > > > If everything is working as it should then it depends on what you have > > > called > > > the setter. If it begins with "set" then pyuic (and uic) should use it > > > directly and not use setProperty(). However this has probably not had > a > > > lot > > > of testing. > > > > > > What have you called your setter? > > > > Let's say the property is called "value". I called my setter _set_value, > > pyuic inferred the setter's name to be setValue. > > > > Does uic behave differently to pyuic? > > > > > > I haven't used uic for some time, but this point is kind of moot since > C++ > > doesn't have properties while Python does :) > > Qt/C++ does have properties. > > > The point is that I can't see > > that there is any reason for pyuic to try and use the setter method, > when > > it can simply use the property (i.e., obj.value = something). > > Because it needs to have the same behaviour as uic. If it doesn't then it > is > clearly a pyuic bug. If not then it may be a bug in the implementation of > pyqtProperty.
I'm not sure I follow you here, but I'll let you comment on my attached example first. Can you send me a .ui file? Better yet, I've attached a modified PyDemo example where the setZoom method is renamed to _set_zoom (to mimic my naming convention) and a basic form using the widget. This illustrates the problem. There's no problem modifying PyDemo's zoom property as it were another attribute, e.g., demo.zoom = 1, but the pyuic generated code insists on calling setZoom which isn't there. Arve
#!/usr/bin/env python # A demonstration custom widget. # # Copyright (c) 2007 Riverbank Computing Limited from PyQt4 import QtCore, QtGui # The purpose of this class is to show that Designer's property editor shows # all Python classes in the hierarchy that define properties. class PyTextViewer(QtGui.QTextEdit): # Initialise the instance. def __init__(self, parent=None): QtGui.QTextEdit.__init__(self, parent) self.setReadOnly(True) # Initialise the author property by calling it's reset function. self.resetAuthor() # The getter for the author property. Note that we cannot follow the Qt # naming convention (ie. by using the naming the getter "author") because # it would conflict with the property name. def getAuthor(self): return self._author # The setter for the author property. def setAuthor(self, name): self._author = name # The resetter for the author property. Only Qt Designer uses this. Qt # Designer does not use the deleter function of the property. def resetAuthor(self): self._author = "David Boddie" # Define the author property. This will look like a C++ property to Qt # Designer and a Python property to Python. author = QtCore.pyqtProperty("QString", getAuthor, setAuthor, resetAuthor) # This is the class that implements the custom widget. class PyDemo(PyTextViewer): # Define the Qt signals as a sequence of C++ function signatures excluding # the return type. These may be connected to other signals or slots in Qt # Designer. __pyqtSignals__ = ("zoomChanged(int)") # Initialise the instance. def __init__(self, parent=None): PyTextViewer.__init__(self, parent) self.setWindowTitle("PyQt Demonstration Widget") self.setText(_demo_text) # Initialise the zoom property. We don't just call the resetter # because it assumes that this has already been initialised. self._zoom = 0 # The getter for the zoom property. def getZoom(self): return self._zoom # The setter for the zoom property. We also make define this as a Qt slot # which can be connected to Qt signals in Qt Designer. @QtCore.pyqtSignature("int") def _set_zoom(self, zoom): # Don't do anything if nothing has changed. if self._zoom == zoom: return # Zoom in or out according to the relative zoom levels. if self._zoom < zoom: self.zoomIn(zoom - self._zoom) elif self._zoom > zoom: self.zoomOut(self._zoom - zoom) # Remember the new zoom level. self._zoom = zoom # Emit the Qt signal to say that the zoom level has changed. self.emit(QtCore.SIGNAL("zoomChanged(int)"), zoom) # The resetter for the zoom property. def resetZoom(self): self._set_zoom(0) # Define the zoom property. Changing the value of this in Qt Designer's # property editor causes the zoom level to change dynamically. zoom = QtCore.pyqtProperty("int", getZoom, _set_zoom, resetZoom) # The text displayed in the custom widget. _demo_text = """<h3>PyQt Demonstration Widget</h3> <p>This simple example demonstrates the following features.</p> <ul> <li>The definition of properties that behave as C++ properties to Qt and Python properties to Python.</li> <li>The definition of new Qt signals that can be connected to other signals and Qt slots in Designer.</li> <li>The definition of new Qt slots that can be connected to signals in Designer.</li> </ul> """ # Display the custom widget if the script is being run directly from the # command line. if __name__ == "__main__": import sys app = QtGui.QApplication(sys.argv) demo = PyDemo() demo.show() sys.exit(app.exec_())
# A demonstration custom widget plugin for Qt Designer. # # Copyright (c) 2007 Riverbank Computing Limited. from PyQt4 import QtGui, QtDesigner from pydemo import PyDemo # This class implements the interface expected by Qt Designer to access the # custom widget. See the description of the QDesignerCustomWidgetInterface # class for full details. class PyDemoPlugin(QtDesigner.QPyDesignerCustomWidgetPlugin): # Initialise the instance. def __init__(self, parent=None): QtDesigner.QPyDesignerCustomWidgetPlugin.__init__(self) self._initialized = False # Initialise the custom widget for use with the specified formEditor # interface. def initialize(self, formEditor): if self._initialized: return self._initialized = True # Return True if the custom widget has been intialised. def isInitialized(self): return self._initialized # Return a new instance of the custom widget with the given parent. def createWidget(self, parent): return PyDemo(parent) # Return the name of the class that implements the custom widget. def name(self): return "PyDemo" # Return the name of the group to which the custom widget belongs. A new # group will be created if it doesn't already exist. def group(self): return "PyQt Examples" # Return the icon used to represent the custom widget in Designer's widget # box. def icon(self): return QtGui.QIcon(_logo_pixmap) # Return a short description of the custom widget used by Designer in a # tool tip. def toolTip(self): return "PyQt demonstration widget" # Return a full description of the custom widget used by Designer in # "What's This?" help for the widget. def whatsThis(self): return "PyDemo is a demonstration custom widget written in Python " \ "using PyQt." # Return True if the custom widget acts as a container for other widgets. def isContainer(self): return False # Return an XML fragment that allows the default values of the custom # widget's properties to be overridden. def domXml(self): return '<widget class="PyDemo" name="pyDemo">\n' \ ' <property name="toolTip" >\n' \ ' <string>PyQt demonstration widget</string>\n' \ ' </property>\n' \ ' <property name="whatsThis" >\n' \ ' <string>PyDemo is a demonstration custom widget written ' \ 'in Python using PyQt.</string>\n' \ ' </property>\n' \ '</widget>\n' # Return the name of the module containing the class that implements the # custom widget. It may include a module path. def includeFile(self): return "pydemo" # Define the image used for the icon. _logo_16x16_xpm = [ "16 16 6 1", " c None", ". c #FFFFFF", "a c #01E0FC", "b c #D8D508", "c c #01AC01", "d c #0180E8", "aaa...bbbb...aaa", "aaaa.bbbbbb.aaaa", "aaaa.bbbbbb.aaaa", "aaaa.bbbbbb.aaaa", "aaa...bbbb...aaa", "................", "cccccccccccccccc", "cccccccccccccccc", "cccccccccccccccc", "cccccccccccccccc", "................", "dddddddddddddddd", "dddddddddddddddd", "dddddddddddddddd", "dddddddddddddddd", " "] _logo_pixmap = QtGui.QPixmap(_logo_16x16_xpm)
pydemo.ui
Description: Binary data
_______________________________________________ PyQt mailing list PyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt