Ceci est un mémo sur la façon de créer un widget avec PyQt et de l'utiliser sur le concepteur Qt. Il comprend également la mise en œuvre du signal et du slot en tant que fonctions. L'exemple utilise Qt4, mais Qt5 est fondamentalement le même (bien que certaines modifications soient nécessaires). J'ai cherché sur le net, mais cela n'a pas frappé facilement, donc je pense que ce sera utile. Certains termes ont été nommés arbitrairement par moi, donc je vous serais reconnaissant de bien vouloir signaler ceux qui s'écartent des règles Qt.
Tout d'abord, créez un widget de test qui fonctionne avec PyQt dans le concepteur. L'apparence est On dirait. QLavel, QTextInput, QPushbutton sont disposés dans QHBoxLayout. Le nom de l'objet est TextInp. Le signal cliqué du QPushButton est connecté au clear de QTextInput et au slot getPressed de Form. L'emplacement getPressed a été créé sur le concepteur. Enregistrez-le dans le fichier ui_textinp.ui.
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>TextInp</class>
<widget class="QWidget" name="TextInp">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>62</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<widget class="QWidget" name="horizontalLayoutWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>391</width>
<height>61</height>
</rect>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineEdit"/>
</item>
<item>
<widget class="QPushButton" name="pushButton">
<property name="text">
<string>PushButton</string>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
<resources/>
<connections>
<connection>
<sender>pushButton</sender>
<signal>clicked()</signal>
<receiver>lineEdit</receiver>
<slot>clear()</slot>
<hints>
<hint type="sourcelabel">
<x>358</x>
<y>31</y>
</hint>
<hint type="destinationlabel">
<x>238</x>
<y>32</y>
</hint>
</hints>
</connection>
<connection>
<sender>pushButton</sender>
<signal>clicked()</signal>
<receiver>TextInp</receiver>
<slot>getPressed()</slot>
<hints>
<hint type="sourcelabel">
<x>383</x>
<y>31</y>
</hint>
<hint type="destinationlabel">
<x>394</x>
<y>51</y>
</hint>
</hints>
</connection>
</connections>
<slots>
<slot>getPressed()</slot>
</slots>
</ui>
Ce fichier d'interface utilisateur utilisant pyuic4
$ pyuic4 ui_textinp.ui > ui_textinp.py
Convertir en. Une classe nommée Ui_TextInp est générée dans le fichier python généré. Ce nom vient du nom d'objet TextInp.
Ensuite, créez une application dans laquelle ce widget fonctionne indépendamment. Avec le nom textinp.py
#!/usr/bin/env python
import PyQt4
from PyQt4 import QtCore,QtGui
from PyQt4.QtGui import QApplication,QWidget,QVBoxLayout
__version__ = '0.0.1'
from ui_textinp import Ui_TextInp
try:
_fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
_fromUtf8 = lambda s: s
class TextInp(QWidget, Ui_TextInp):
def __init__(self, parent=None):
super(TextInp, self).__init__(parent)
self.setupUi(self)
vBox = QVBoxLayout()
vBox.addWidget(self.horizontalLayoutWidget)
self.setLayout(vBox)
@QtCore.pyqtSlot()
def getPressed(self):
print "PRESSED"
if __name__ == '__main__':
app = QApplication(sys.argv)
textinp = TextInp()
textinp.show()
sys.exit(app.exec_())
Je ne pense pas que vous ayez besoin de beaucoup de commentaires. La classe TextInp hérite de Ui_TextInp. Sans vBox, la taille ne suivra pas lorsque vous modifiez la taille de la fenêtre. Vous pouvez voir l'implémentation du slot. Lorsque vous cliquez sur QPushButton, la fonction getPressed est appelée et la chaîne PRSSED s'affiche dans la sortie standard. Quand tu cours
$ python textinp.py
Le widget comme indiqué ci-dessus sera affiché, la chaîne de caractères saisie dans le texte sera effacée en appuyant sur le bouton, et PRESSED sera affiché dans la sortie standard.
Vous avez maintenant un widget que vous pouvez exécuter avec PyQt. Vous avez besoin d'un autre fichier python pour l'importer en tant que composant de concepteur. Appelons cela textinpplugin.py. Le fichier est le suivant.
#!/usr/bin/env python
"""
polygonwidgetplugin.py
A polygon widget custom widget plugin for Qt Designer.
Copyright (C) 2006 David Boddie <[email protected]>
Copyright (C) 2005-2006 Trolltech ASA. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
"""
from PyQt4 import QtGui, QtDesigner
from textinp import TextInp
class TextInpPlugin(QtDesigner.QPyDesignerCustomWidgetPlugin):
"""TextInpPlugin(QtDesigner.QPyDesignerCustomWidgetPlugin)
Provides a Python custom plugin for Qt Designer by implementing the
QDesignerCustomWidgetPlugin via a PyQt-specific custom plugin class.
"""
# The __init__() method is only used to set up the plugin and define its
# initialized variable.
def __init__(self, parent=None):
super(TextInpPlugin, self).__init__(parent)
self.initialized = False
# The initialize() and isInitialized() methods allow the plugin to set up
# any required resources, ensuring that this can only happen once for each
# plugin.
def initialize(self, core):
if self.initialized:
return
self.initialized = True
def isInitialized(self):
return self.initialized
# This factory method creates new instances of our custom widget with the
# appropriate parent.
def createWidget(self, parent):
return TextInp(parent)
# This method returns the name of the custom widget class that is provided
# by this plugin.
def name(self):
return "TextInp"
# Returns the name of the group in Qt Designer's widget box that this
# widget belongs to.
def group(self):
return "Example for Qiita"
# Returns the icon used to represent the custom widget in Qt Designer's
# widget box.
def icon(self):
return QtGui.QIcon(_logo_pixmap)
# Returns a short description of the custom widget for use in a tool tip.
def toolTip(self):
return ""
# Returns a short description of the custom widget for use in a "What's
# This?" help message for the widget.
def whatsThis(self):
return ""
# Returns True if the custom widget acts as a container for other widgets;
# otherwise returns False. Note that plugins for custom containers also
# need to provide an implementation of the QDesignerContainerExtension
# interface if they need to add custom editing support to Qt Designer.
def isContainer(self):
return False
# Returns an XML description of a custom widget instance that describes
# default values for its properties. Each custom widget created by this
# plugin will be configured using this description.
def domXml(self):
return '<widget class="TextInp" name="textinp" />\n'
# Returns the module containing the custom widget class. It may include
# a module path.
def includeFile(self):
return "textinp"
# Define the image used for the icon.
_logo_16x16_xpm = [
"16 16 3 1",
"a c #008000",
"# c #0080ff",
". c #ffffff",
"................",
"................",
"..#############.",
"..#############.",
"..#############.",
"..#############.",
"..#############.",
"..#############.",
"................",
"................",
"..aaaaaaaaaaaaa.",
"..aaaaaaaaaaaaa.",
"..aaaaaaaaaaaaa.",
"..aaaaaaaaaaaaa.",
"..aaaaaaaaaaaaa.",
"................"]
_logo_pixmap = QtGui.QPixmap(_logo_16x16_xpm)
Je pense qu'il peut être appliqué en réécrivant textinp et TextInp. La chaîne retournée par def group sera le groupe de widgets du concepteur. De plus, le dernier _logo_16x16_xpm est une icône au format xpm.
Jusque là,
textinp.py
ui_textinp.py
textinpplugin.py
Trois fichiers sont créés.
Parmi ceux-ci, déplacez les fichiers liés au widget vers les widgets et les fichiers liés au plugin dans un sous-répertoire appelé python, définissez les variables d'environnement PYQTDESIGNERPATH et PYTHONPATH, et démarrez le concepteur.
$ mv textinp.py ui_textinp.py widgets
$ mv textinpplugin.py python
$ export PYQTDESIGNERPATH=python
$ export PYTHONPATH=widgets
$ designer
Vous devriez voir un widget comme celui ci-dessous dans la boîte de widget du concepteur. Toutes nos félicitations. Le widget que vous avez créé peut maintenant être utilisé sur le concepteur comme n'importe quel autre widget.
De plus, le slot getPressed défini ci-dessus est également valide dans l'éditeur de signal / slot du concepteur.
signal, property
Oups, j'ai implémenté le slot, mais le signal n'était pas encore là. Ajoutez-le à textinp.py plus tôt. Ecrire pour générer (émettre) un signal lorsque getPressed est appelé. Écrivez QtCore.pyqtSignal au début de la définition de classe et appelez outText.emit ("TXT") lorsque vous voulez l'appeler.
class TextInp(QWidget, Ui_TextInp):
outText=QtCore.pyqtSignal(str)
def __init__(self, parent=None):
super(TextInp, self).__init__(parent)
self.setupUi(self)
vBox = QVBoxLayout()
vBox.addWidget(self.horizontalLayoutWidget)
self.setLayout(vBox)
self._label_text="Label text"
self.label.setText(self._label_text)
@QtCore.pyqtSlot()
def getPressed(self):
self.outText.emit(self.lineEdit.text())
print self.lineEdit.text()
Vous pouvez voir que le signal est implémenté dans le concepteur.
Textinp.py qui implémente la propriété.
class TextInp(QWidget, Ui_TextInp):
outText=QtCore.pyqtSignal(str)
def __init__(self, parent=None):
super(TextInp, self).__init__(parent)
self.setupUi(self)
vBox = QVBoxLayout()
vBox.addWidget(self.horizontalLayoutWidget)
self.setLayout(vBox)
self._label_text="Label text"
self.label.setText(self._label_text)
@QtCore.pyqtSlot()
def getPressed(self):
self.outText.emit(self.lineEdit.text())
print self.lineEdit.text()
def setLabelText(self,inptxt):
self._label_text=inptxt
self.label.setText(self._label_text)
def getLabelText(self):
return self._label_text
label_text=QtCore.pyqtProperty(str, getLabelText, setLabelText)
Définissez les fonctions setLabelText et getLabelText dans QtCore.pyqtProperty. Sur le designer Label_text peut être spécifié comme suit.
Recommended Posts