Dies ist ein Memo darüber, wie Sie ein Widget mit PyQt erstellen und im Qt-Designer verwenden. Es beinhaltet auch die Implementierung von Signal und Slot als Funktionen. Das Beispiel verwendet Qt4, aber Qt5 ist im Grunde dasselbe (obwohl einige Modifikationen erforderlich sind). Ich habe im Internet gesucht, aber es hat nicht leicht getroffen, deshalb denke ich, dass es hilfreich sein wird. Einige der Begriffe wurden von mir willkürlich benannt, daher wäre ich Ihnen dankbar, wenn Sie auf etwas hinweisen könnten, das von den Qt-Regeln abweicht.
Erstellen Sie zunächst ein Test-Widget, das mit PyQt im Designer funktioniert. Das Aussehen ist Es sieht aus wie. QLavel, QTextInput, QPushbutton sind in QHBoxLayout angeordnet. Der Objektname lautet TextInp. Das angeklickte Signal des QPushButton ist mit dem Löschen von QTextInput und dem getPressed-Slot von Form verbunden. Der getPressed-Slot wurde auf dem Designer erstellt. Speichern Sie dies in der Datei 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>
Diese UI-Datei mit pyuic4
$ pyuic4 ui_textinp.ui > ui_textinp.py
Konvertieren zu. In der generierten Python-Datei wird eine Klasse mit dem Namen Ui_TextInp generiert. Dieser Name stammt vom Objektnamen TextInp.
Erstellen Sie als Nächstes eine Anwendung, in der dieses Widget unabhängig arbeitet. Mit dem Namen 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_())
Ich glaube nicht, dass Sie viel Kommentar brauchen. Die TextInp-Klasse erbt von Ui_TextInp. Ohne vBox folgt die Größe nicht, wenn Sie die Fenstergröße ändern. Sie können die Implementierung von Slot sehen. Wenn Sie auf den QPushButton klicken, wird die Funktion getPressed aufgerufen und die PRSSED-Zeichenfolge in der Standardausgabe angezeigt. Wenn du rennst
$ python textinp.py
Das oben gezeigte Widget wird angezeigt, die im Text eingegebene Zeichenfolge wird durch Drücken der Taste gelöscht und PRESSED wird in der Standardausgabe angezeigt.
Jetzt haben Sie ein Widget, das Sie mit PyQt ausführen können. Sie benötigen eine andere Python-Datei, um diese als Designer-Teil zu importieren. Nennen wir dies textinpplugin.py. Die Datei ist wie folgt.
#!/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)
Ich denke, dass es durch Umschreiben von textinp und TextInp angewendet werden kann. Die von def group zurückgegebene Zeichenfolge ist die Widgetgruppe des Designers. Außerdem ist das letzte _logo_16x16_xpm ein Symbol im xpm-Format.
Bisher,
textinp.py
ui_textinp.py
textinpplugin.py
Es werden drei Dateien erstellt.
Verschieben Sie die Widget-bezogenen Dateien in die Widgets und die Plugin-bezogenen Dateien in ein Unterverzeichnis namens Python, definieren Sie die Umgebungsvariablen PYQTDESIGNERPATH und PYTHONPATH und starten Sie den Designer.
$ mv textinp.py ui_textinp.py widgets
$ mv textinpplugin.py python
$ export PYQTDESIGNERPATH=python
$ export PYTHONPATH=widgets
$ designer
Sie sollten ein Widget wie das folgende im Widget-Feld des Designers sehen. Herzliche Glückwünsche. Das von Ihnen erstellte Widget kann jetzt wie jedes andere Widget im Designer verwendet werden.
Der oben definierte getPressed-Steckplatz ist auch im Signal- / Steckplatz-Editor des Designers gültig.
signal, property
Hoppla, ich habe einen Slot implementiert, aber das Signal war noch nicht da. Fügen Sie es früher zu textinp.py hinzu. Schreiben Sie, um ein Signal zu erzeugen (auszusenden), wenn getPressed aufgerufen wird. Schreiben Sie QtCore.pyqtSignal am Anfang der Klassendefinition und rufen Sie outText.emit ("TXT") auf, wenn Sie es aufrufen möchten.
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()
Sie können sehen, dass das Signal im Designer implementiert ist.
Textinp.py, das die Eigenschaft implementiert.
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)
Definieren Sie die Funktionen setLabelText und getLabelText in QtCore.pyqtProperty. Auf den Designer Label_text kann wie folgt angegeben werden.
Recommended Posts