Erstellen Sie Qt-Designerteile mit Python (PyQt)

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.

Dinge vorzubereiten

  1. Widget, das mit PyQt funktioniert.
  2. Python-Datei zum Definieren von Plugins Nur diese beiden.

Widget erstellen

Erstellen Sie zunächst ein Test-Widget, das mit PyQt im Designer funktioniert. Das Aussehen ist preview.png 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.

Erstellen einer Plugin-Definitionsdatei

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.

Starten Sie den Designer

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. a.png 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. sigslot.png

signal, property

Signalimplementierung

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. sig2.png

Implementierung von Eigentum

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 property_editor.png Label_text kann wie folgt angegeben werden.

Recommended Posts

Erstellen Sie Qt-Designerteile mit Python (PyQt)
Erstellen Sie Spatia Lite in Python
Erstellen Sie eine Funktion in Python
[GUI in Python] PyQt5 -Widget-
[Maya Python] Anzeige .ui erstellt von Qt Designer in Maya
Einführung in die GUI: PyQt5 in Python
[GUI in Python] PyQt5 -Event-
Erstellen Sie einen DI-Container mit Python
Erstellen Sie eine Binärdatei in Python
Erstellen Sie Google Mail in Python ohne Verwendung der API
Erstellen Sie eine Python-Projektdokumentation in Sphinx
Erstellen Sie eine zufällige Zeichenfolge in Python
Erstellen und lesen Sie Messagepacks in Python
Erstellen Sie Ihre eigenen Linux-Befehle in Python
Erstellen Sie ScriptableObject in Python, wenn Sie ADX2 erstellen
[LLDB] Erstellen Sie Ihren eigenen Befehl mit Python
Erstellen Sie eine einfache GUI-App in Python
[GPS] Erstellen Sie eine kml-Datei mit Python
Quadtree in Python --2
CURL in Python
Metaprogrammierung mit Python
Erstellen Sie in 1 Minute eine Vim + Python-Testumgebung
Python 3.3 mit Anaconda
Geokodierung in Python
SendKeys in Python
Erstellen Sie eine GIF-Datei mit Pillow in Python
Metaanalyse in Python
Unittest in Python
Ich möchte mit Python ein Fenster erstellen
So erstellen Sie eine JSON-Datei in Python
Erstellen Sie automatisch Wort- und Excel-Berichte mit Python
Erstellen Sie eine virtuelle Umgebung mit conda in Python
Zwietracht in Python
Deutsch in Python
DCI in Python
Quicksort in Python
nCr in Python
N-Gramm in Python
Programmieren mit Python
Erstellen Sie eine Farbleiste mit Python + Qt (PySide)
Plink in Python
Konstante in Python
Erstellen Sie ein Bild mit Zeichen mit Python (Japanisch)
Erstellen Sie in Python ein einfaches Momentum-Investmentmodell
FizzBuzz in Python
SQLite in Python
Schritt AIC in Python
Erstellen Sie eine neue Seite im Zusammenfluss mit Python
Erstellen Sie mit Python + Qt (PySide) ein farbspezifisches Widget.
Erstellen Sie ein Datum / Uhrzeit-Objekt aus einer Zeichenfolge in Python (Python 3.3).
LINE-Bot [0] in Python
Erstellen Sie in Python ein Paket mit globalen Befehlen
CSV in Python
Reverse Assembler mit Python
Reflexion in Python
Konstante in Python