Редактирование: Designing Custom Controls with PyQt

Материал из Wiki.crossplatform.ru

Перейти к: навигация, поиск
Внимание: Вы не представились системе. Ваш IP-адрес будет записан в историю изменений этой страницы.
Правка может быть отменена. Пожалуйста, просмотрите сравнение версий, чтобы убедиться, что это именно те изменения, которые вас интересуют, и нажмите «Записать страницу», чтобы изменения вступили в силу.
Текущая версия Ваш текст
Строка 1: Строка 1:
-
{{Панель навигации по Qt Quarterly|Выпуск 26}}
+
{{Категория:Qt_Издания}}
-
 
+
[[Категория:Qt_Издания]]
__NOTOC__
__NOTOC__
==Designing Custom Controls with PyQt==
==Designing Custom Controls with PyQt==
-
by David Boddie<br /><div class="introduction"><br />Одной из скрытых особенностей PyQt является его способность разрешить пользовательские плагины виджетов, которые будут созданы для Qt Designer'а, используя модули написаные на чистом Python. Это не только открывает интересные возможности для Python программистов, но и позволяет разработчикам и дизайнерам экспериментировать с быстрым прототипированием без нервотрепки создания общей библиотеки для плагинов.<br />
+
by David Boddie<br /><div class="introduction"><br />One of the hidden features of PyQt is its ability to allow custom widgetplugins to be created for Qt Designer using modules written in pure Pythoncode. Not only does this open up some interesting possibilities for Pythonprogrammers, it also lets developers and designers experiment with rapidprototyping without the hassle of building shared libraries for plugins.<br />
*[[#creatingacustomwidget | Creating a Custom Widget]]
*[[#creatingacustomwidget | Creating a Custom Widget]]
*[[#producingaplugin | Producing a Plugin]]
*[[#producingaplugin | Producing a Plugin]]
Строка 12: Строка 12:
*[[#takingthingsfurther | Taking Things Further]]
*[[#takingthingsfurther | Taking Things Further]]
</div>
</div>
-
When [[Qt:Документация 4.3.2/designer-manual | Qt Designer]] was redesigned and rewritten for Qt 4, one of the main aims was tomake it easier for developers to add their own custom controls to thestandard Qt widgets available to designers. Although the creators of [[Qt:Документация 4.3.2/designer-manual | Qt Designer]] hadC++ programmers in mind when they implemented this feature, such extensibilityisn't limited to just this one language&mdash;any set of language bindings that useQt's meta-object system can join in the fun.
+
When [[Qt:Документация 4.4.3/designer-manual | Qt Designer]] was redesigned and rewritten for Qt 4, one of the main aims was tomake it easier for developers to add their own custom controls to thestandard Qt widgets available to designers. Although the creators of [[Qt:Документация 4.4.3/designer-manual | Qt Designer]] hadC++ programmers in mind when they implemented this feature, such extensibilityisn't limited to just this one language&mdash;any set of language bindings that useQt's meta-object system can join in the fun.
[[Image:qq26-pyqtwidget.png|center]]
[[Image:qq26-pyqtwidget.png|center]]
-
In this article, we will show how to use PyQt to create widgets that can beused in [[Qt:Документация 4.3.2/designer-manual | Qt Designer]], describe the process of making plugins, and look at themechanisms that expose Qt's meta-object system to Python.
+
In this article, we will show how to use PyQt to create widgets that can beused in [[Qt:Документация 4.4.3/designer-manual | Qt Designer]], describe the process of making plugins, and look at themechanisms that expose Qt's meta-object system to Python.
<div id="creatingacustomwidget"></div>
<div id="creatingacustomwidget"></div>
===Creating a Custom Widget===
===Creating a Custom Widget===
-
PyQt exposes the Qt APIs to Python in a fairly conservative way, making theconstruction of custom widgets a familiar experience to C++ programmers. Newwidgets are subclassed from [[Qt:Документация 4.3.2/qwidget | QWidget]] in the usual way, as we can see withthis fully-functioning widget for entering latitude and longitude values:
+
PyQt exposes the Qt APIs to Python in a fairly conservative way, making theconstruction of custom widgets a familiar experience to C++ programmers. Newwidgets are subclassed from [[Qt:Документация 4.4.3/qwidget | QWidget]] in the usual way, as we can see withthis fully-functioning widget for entering latitude and longitude values:
<source lang="cpp-qt">
<source lang="cpp-qt">
class GeoLocationWidget(QWidget):
class GeoLocationWidget(QWidget):
Строка 70: Строка 70:
                   latitude)
                   latitude)
</source>  
</source>  
-
Just as in a C++ class, we define methods called <tt>latitude()</tt> and<tt>setLatitude()</tt> to provide the property's functionality. The declarationimmediately before the setter is a special Python decorator that tellsQt that <tt>setLatitude()</tt> is a slot and that it accepts double precisionfloating point values. Typically, this kind of declarationis not required with PyQt&mdash;any function or method can be used as aslot&mdash;but this makes interacting with [[Qt:Документация 4.3.2/designer-manual | Qt Designer]] easier later on.
+
Just as in a C++ class, we define methods called <tt>latitude()</tt> and<tt>setLatitude()</tt> to provide the property's functionality. The declarationimmediately before the setter is a special Python decorator that tellsQt that <tt>setLatitude()</tt> is a slot and that it accepts double precisionfloating point values. Typically, this kind of declarationis not required with PyQt&mdash;any function or method can be used as aslot&mdash;but this makes interacting with [[Qt:Документация 4.4.3/designer-manual | Qt Designer]] easier later on.
The <tt>pyqtProperty()</tt> function is used to register the property with Qt:
The <tt>pyqtProperty()</tt> function is used to register the property with Qt:
Строка 79: Строка 79:
===Producing a Plugin===
===Producing a Plugin===
-
The process of making the widget work is very similar tothat for C++ widgets. Each custom widget class is represented by aplugin class that creates instances of it (as described inQt Quarterly 16).The main difference is that [[Qt:Документация 4.3.2/designer-manual | Qt Designer]]'s plugin interfaces are used viaspecial PyQt-specific plugin classes.
+
The process of making the widget work is very similar tothat for C++ widgets. Each custom widget class is represented by aplugin class that creates instances of it (as described inQt Quarterly 16).The main difference is that [[Qt:Документация 4.4.3/designer-manual | Qt Designer]]'s plugin interfaces are used viaspecial PyQt-specific plugin classes.
[[Image:qq26-pyqtwidget-box.png|center]]
[[Image:qq26-pyqtwidget-box.png|center]]
Строка 95: Строка 95:
The code to initialize an instance of the class should be familiarto writers of C++ widget plugins.
The code to initialize an instance of the class should be familiarto writers of C++ widget plugins.
-
The <tt>initialize()</tt> method is called by [[Qt:Документация 4.3.2/designer-manual | Qt Designer]] after the plugin hasbeen loaded. Plugins use this opportunity to install extensions tothe form editor.
+
The <tt>initialize()</tt> method is called by [[Qt:Документация 4.4.3/designer-manual | Qt Designer]] after the plugin hasbeen loaded. Plugins use this opportunity to install extensions tothe form editor.
<source lang="cpp-qt">
<source lang="cpp-qt">
   def initialize(self, formEditor):
   def initialize(self, formEditor):
Строка 127: Строка 127:
</source>  
</source>  
-
For widgets created with Python, the <tt>includeFile()</tt> method returns thename of the module that provides the named class. In this case, the moduleresides within the [[Qt:Документация 4.3.2/qq_widgets | QQ_Widgets]] package.
+
For widgets created with Python, the <tt>includeFile()</tt> method returns thename of the module that provides the named class. In this case, the moduleresides within the [[Qt:Документация 4.4.3/qq_widgets | QQ_Widgets]] package.
<div id="makingamenu"></div>
<div id="makingamenu"></div>
===Making a Menu===
===Making a Menu===
-
Although it is quite easy to edit the properties of the custom widget in [[Qt:Документация 4.3.2/designer-manual | Qt Designer]]'sproperty editor, we will create a dialog that the user can open to change themin a more natural way. The dialog will be available from a new entry on theform's context menu whenever the user has selected the custom widget.
+
Although it is quite easy to edit the properties of the custom widget in [[Qt:Документация 4.4.3/designer-manual | Qt Designer]]'sproperty editor, we will create a dialog that the user can open to change themin a more natural way. The dialog will be available from a new entry on theform's context menu whenever the user has selected the custom widget.
The dialog itself isn't very special. It operates on a widget passed to itfrom elsewhere, providing another <tt>GeoLocationWidget</tt> for the user to modifyand preview changes in.
The dialog itself isn't very special. It operates on a widget passed to itfrom elsewhere, providing another <tt>GeoLocationWidget</tt> for the user to modifyand preview changes in.
Строка 211: Строка 211:
Note that the <tt>updateLocation()</tt> slot is not decorated in this case&mdash;sincewe make the connection, there's no need to declare it. Another short cut isthe use of a Python list in the <tt>taskActions()</tt> method.
Note that the <tt>updateLocation()</tt> slot is not decorated in this case&mdash;sincewe make the connection, there's no need to declare it. Another short cut isthe use of a Python list in the <tt>taskActions()</tt> method.
-
Each task menu extension is created by the task menu factory that weregistered in the <tt>initialize()</tt> method of our custom widget plugin.When the user opens a context menu over a custom widget, [[Qt:Документация 4.3.2/designer-manual | Qt Designer]] creates a newtask menu extension by calling the factory's <tt>createExtension()</tt> method.
+
Each task menu extension is created by the task menu factory that weregistered in the <tt>initialize()</tt> method of our custom widget plugin.When the user opens a context menu over a custom widget, [[Qt:Документация 4.4.3/designer-manual | Qt Designer]] creates a newtask menu extension by calling the factory's <tt>createExtension()</tt> method.
<source lang="cpp-qt">
<source lang="cpp-qt">
class GeoLocationTaskMenuFactory(QExtensionFactory):
class GeoLocationTaskMenuFactory(QExtensionFactory):
Строка 236: Строка 236:
===Putting Things in Place===
===Putting Things in Place===
-
On systems where [[Qt:Документация 4.3.2/designer-manual | Qt Designer]] is ableto use third party plugins, and where PyQt includes the <tt>QtDesigner</tt>module, it should be possible to use plugins written with PyQt. Unlike C++plugins, those written in Python do not have to be compiled or otherwiseprepared before we install them&mdash;we can simply copy the sources to theappropriate locations so that[[Qt:Документация 4.3.2/designer-manual | Qt Designer]] can find them.
+
On systems where [[Qt:Документация 4.4.3/designer-manual | Qt Designer]] is ableto use third party plugins, and where PyQt includes the <tt>QtDesigner</tt>module, it should be possible to use plugins written with PyQt. Unlike C++plugins, those written in Python do not have to be compiled or otherwiseprepared before we install them&mdash;we can simply copy the sources to theappropriate locations so that[[Qt:Документация 4.4.3/designer-manual | Qt Designer]] can find them.
-
The Python modules that provide the plugin and task menu extension aretypically stored together as files in the same directory. [[Qt:Документация 4.3.2/designer-manual | Qt Designer]] plugins writtenin C++ are usually installed in a <tt>designer</tt> subdirectory within thedirectory described by [[Qt:Документация 4.3.2/qlibraryinfo | QLibraryInfo]]::PluginPath. The convention forPython plugins is to create a <tt>python</tt> directory alongside the C++ pluginsand store them in there.
+
The Python modules that provide the plugin and task menu extension aretypically stored together as files in the same directory. [[Qt:Документация 4.4.3/designer-manual | Qt Designer]] plugins writtenin C++ are usually installed in a <tt>designer</tt> subdirectory within thedirectory described by [[Qt:Документация 4.4.3/qlibraryinfo | QLibraryInfo]]::PluginPath. The convention forPython plugins is to create a <tt>python</tt> directory alongside the C++ pluginsand store them in there.
The widgets themselves need to be placed in a standard location so that thePython interpreter can find them. Often, it is convenient to store them in thePython installation's <tt>site-packages</tt> directory since they are going to beneeded by applications that use forms containing those widgets. Theinstallation procedure involves creating a <tt>setup.py</tt> file which we won'tdiscuss here&mdash;the code archive accompanying this article contains a filethat can be used as a starting point for your own projects.
The widgets themselves need to be placed in a standard location so that thePython interpreter can find them. Often, it is convenient to store them in thePython installation's <tt>site-packages</tt> directory since they are going to beneeded by applications that use forms containing those widgets. Theinstallation procedure involves creating a <tt>setup.py</tt> file which we won'tdiscuss here&mdash;the code archive accompanying this article contains a filethat can be used as a starting point for your own projects.
-
As an alternative to installation, environment variables can be set to referto the locations of plugins and custom widgets. Developers familiar withPython will know that <tt>PYTHONPATH</tt> can be used to add new directories to thelist of known locations of modules and packages.Similarly, PY[[Qt:Документация 4.3.2/qtdesignerpath | QTDESIGNERPATH]] can be used to add locations of Python modulescontaining plugins and extensions for [[Qt:Документация 4.3.2/designer-manual | Qt Designer]].
+
As an alternative to installation, environment variables can be set to referto the locations of plugins and custom widgets. Developers familiar withPython will know that <tt>PYTHONPATH</tt> can be used to add new directories to thelist of known locations of modules and packages.Similarly, PY[[Qt:Документация 4.4.3/qtdesignerpath | QTDESIGNERPATH]] can be used to add locations of Python modulescontaining plugins and extensions for [[Qt:Документация 4.4.3/designer-manual | Qt Designer]].
-
With the plugin, extension and custom widget installed, or their locationsspecified using the environment variables described above, we can now run [[Qt:Документация 4.3.2/designer-manual | Qt Designer]]and use our custom widget&mdash;it should be available from the'''Qt Quarterly Examples''' section of the widget box.
+
With the plugin, extension and custom widget installed, or their locationsspecified using the environment variables described above, we can now run [[Qt:Документация 4.4.3/designer-manual | Qt Designer]]and use our custom widget&mdash;it should be available from the'''Qt Quarterly Examples''' section of the widget box.
Forms that contain custom widgets can be processed with the <tt>pyuic4</tt> tool ina way that should be familiar to users of <tt>uic</tt>. Code to import the customwidgets is generated along with the code to create the form, so developerssimply need to make sure that the modules containing them are available whentheir applications are run.
Forms that contain custom widgets can be processed with the <tt>pyuic4</tt> tool ina way that should be familiar to users of <tt>uic</tt>. Code to import the customwidgets is generated along with the code to create the form, so developerssimply need to make sure that the modules containing them are available whentheir applications are run.
Строка 254: Строка 254:
* We declared signals in advance, rather than just emitting custom signalswhen needed.  
* We declared signals in advance, rather than just emitting custom signalswhen needed.  
* We decorated certain methods with <tt>@pyqtSignature()</tt> to indicate thatthey are slots which accept certain argument types.  
* We decorated certain methods with <tt>@pyqtSignature()</tt> to indicate thatthey are slots which accept certain argument types.  
-
* We created properties with <tt>pyqtProperty()</tt> to expose them to [[Qt:Документация 4.3.2/designer-manual | Qt Designer]]'sproperty editor.  
+
* We created properties with <tt>pyqtProperty()</tt> to expose them to [[Qt:Документация 4.4.3/designer-manual | Qt Designer]]'sproperty editor.  
-
Since the use of each feature makes information available to other Qtcomponents, widgets written like this can be supplied to other[[Qt:Документация 4.3.2/qobject | QObject]]-based plugin systems as long as there is a way to executetheir Python source code.
+
Since the use of each feature makes information available to other Qtcomponents, widgets written like this can be supplied to other[[Qt:Документация 4.4.3/qobject | QObject]]-based plugin systems as long as there is a way to executetheir Python source code.
The use of slot and property declarations are also generally useful to Pythonprogrammers. Properties defined in this way behave just like normal Pythonproperties. The slot declarations can be used to help connect signals toslots in a class derived from a form.
The use of slot and property declarations are also generally useful to Pythonprogrammers. Properties defined in this way behave just like normal Pythonproperties. The slot declarations can be used to help connect signals toslots in a class derived from a form.
Строка 274: Строка 274:
Instructions for building and installing the widget plugins described in thisarticle are included in the examples archive,[http://www.crossplatform.ru/uploads/articles/sources/qq26-pyqtdesigner-1.0.zip available from the Qt Quarterly Web site]. We encourage you to try them out and apply the same techniques to your ownwidgets.
Instructions for building and installing the widget plugins described in thisarticle are included in the examples archive,[http://www.crossplatform.ru/uploads/articles/sources/qq26-pyqtdesigner-1.0.zip available from the Qt Quarterly Web site]. We encourage you to try them out and apply the same techniques to your ownwidgets.
-
More detailed instructions about [[Qt:Документация 4.3.2/designer-manual | Qt Designer]] plugins, PyQt and the Python tools thatmake them work together is available from the [http://www.riverbankcomputing.com/static/Docs/PyQt4/pyqt4ref.html RiverbankComputing Web site].
+
More detailed instructions about [[Qt:Документация 4.4.3/designer-manual | Qt Designer]] plugins, PyQt and the Python tools thatmake them work together is available from the [http://www.riverbankcomputing.com/static/Docs/PyQt4/pyqt4ref.html RiverbankComputing Web site].
-
 
+
[http://www.forum.crossplatform.ru/index.php?showtopic=1683 Обсудить на форуме...]
-
[[Категория:Qt_Издания]]
+

Пожалуйста, обратите внимание, что все ваши добавления могут быть отредактированы или удалены другими участниками. Если вы не хотите, чтобы кто-либо изменял ваши тексты, не помещайте их сюда.
Вы также подтверждаете, что являетесь автором вносимых дополнений, или скопировали их из источника, допускающего свободное распространение и изменение своего содержимого (см. Wiki.crossplatform.ru:Авторское право). НЕ РАЗМЕЩАЙТЕ БЕЗ РАЗРЕШЕНИЯ ОХРАНЯЕМЫЕ АВТОРСКИМ ПРАВОМ МАТЕРИАЛЫ!


Шаблоны, использованные на текущей версии страницы: