Layout und Vererbung

Python und das Qt-Toolkit, erstellen von GUIs mittels des Qt-Designers.
Antworten
QTim
User
Beiträge: 7
Registriert: Mittwoch 27. September 2017, 08:58

Freitag 6. Oktober 2017, 11:53

Moin,

ich arbeite mit PyQt5 und Python 3.4 auf einem Pi mit Jessie. Eine Gui hab ich mir erstellt, allerdings kommt es zu folgenden Fehlern:

Code: Alles auswählen

libEGL warning: DRI2: failed to authenticate
QLayout: Attempting to add QLayout "" to QWidget "GTM_Form", which already has a layout
Nummer 1 habe ich erst bekommen als ich Python von 2.7 auf 3.4 geupgradet hab und ich vermute, dass Nummer 2 etwas mit Vererbung zu tun hat, kann mir allerdings beides nicht erklären..
Zudem habe ich warum auch immer einen Button zweimal, den es nur einmal geben sollte? Ich sehe leider nicht, an welcher Stelle der Button der Form ein zweites Mal hinzugefügt wird..

Die Gui soll erstmal nichts können, später kommen noch Plots hinzu.
Hat jemand eine Idee?

Hier mein Code:

Code: Alles auswählen

from PyQt5 import QtCore, QtGui, QtWidgets


from PyQt5.QtWidgets import QApplication, QMainWindow, QMenu, QVBoxLayout, QSizePolicy, QMessageBox, QWidget, QPushButton

from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
import matplotlib.pyplot as plt

import random
##




class Ui_GTM_Form(object):
    def __init__(self):
        super().__init__()
        self.left = 10
        self.top = 10
        self.width = 640
        self.heigth = 400
        self.setupUi(GTM_Form)


    
    def setupUi(self, GTM_Form):
        GTM_Form.setObjectName("GTM_Form")
        GTM_Form.resize(824, 685)
        GTM_Form.setStyleSheet("background-color: rgb(87, 85, 85)")
        self.horizontalLayout_2 = QtWidgets.QHBoxLayout(GTM_Form)
        self.horizontalLayout_2.setContentsMargins(-1, 2, -1, -1)
        self.horizontalLayout_2.setObjectName("horizontalLayout_2")
        self.horizontalLayout = QtWidgets.QHBoxLayout()
        self.horizontalLayout.setObjectName("horizontalLayout")
        spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.horizontalLayout.addItem(spacerItem)
        self.horizontalLayout_2.addLayout(self.horizontalLayout)
        self.verticalLayout = QtWidgets.QVBoxLayout()
        self.verticalLayout.setObjectName("verticalLayout")
        self.BtnStart = QtWidgets.QPushButton(GTM_Form)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.BtnStart.sizePolicy().hasHeightForWidth())
        self.BtnStart.setSizePolicy(sizePolicy)
        font = QtGui.QFont()
        font.setPointSize(15)
        self.BtnStart.setFont(font)
        self.BtnStart.setStyleSheet("color: white")
        self.BtnStart.setObjectName("BtnStart")
        self.verticalLayout.addWidget(self.BtnStart)
        self.BtnEnd = QtWidgets.QPushButton(GTM_Form)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.BtnEnd.sizePolicy().hasHeightForWidth())
        self.BtnEnd.setSizePolicy(sizePolicy)
        font = QtGui.QFont()
        font.setPointSize(15)
        self.BtnEnd.setFont(font)
        self.BtnEnd.setStyleSheet("color: white")
        self.BtnEnd.setObjectName("BtnEnd")
        self.verticalLayout.addWidget(self.BtnEnd)
        self.BtnShutdown = QtWidgets.QPushButton(GTM_Form)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.BtnShutdown.sizePolicy().hasHeightForWidth())
        self.BtnShutdown.setSizePolicy(sizePolicy)
        font = QtGui.QFont()
        font.setPointSize(15)
        self.BtnShutdown.setFont(font)
        self.BtnShutdown.setStyleSheet("color: white")
        self.BtnShutdown.setObjectName("BtnShutdown")
        self.verticalLayout.addWidget(self.BtnShutdown)
        self.horizontalLayout_2.addLayout(self.verticalLayout)


        m = PlotCanvas()
        m.move(0, 0)

        self.retranslateUi(GTM_Form)
        QtCore.QMetaObject.connectSlotsByName(GTM_Form)

    def retranslateUi(self, GTM_Form):
        _translate = QtCore.QCoreApplication.translate
        GTM_Form.setWindowTitle(_translate("GTM_Form", "GTM"))
        self.BtnStart.setText(_translate("GTM_Form", "Start"))
        self.BtnEnd.setText(_translate("GTM_Form", "End"))
        self.BtnShutdown.setText(_translate("GTM_Form", "Shutdown"))


class PlotCanvas(FigureCanvas):
 
    def __init__(self, parent=None, width=5, height=4, dpi=100):
        fig = Figure(figsize=(width, height), dpi=dpi)
        self.axes = fig.add_subplot(111)
 
        FigureCanvas.__init__(self, fig)
        self.setParent(parent)
        #self.horizontalLayout.addPlot(FigureCanvas)
        FigureCanvas.setSizePolicy(self,
                QSizePolicy.Expanding,
                QSizePolicy.Expanding)
        FigureCanvas.updateGeometry(self)
        self.plot()
 
 
    def plot(self):
        
        data = [random.random() for i in range(25)]
        ax = self.figure.add_subplot(111)
        ax.plot(data, 'r-')
        ax.set_title('PyQt Matplotlib Example')
        self.draw()


if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    GTM_Form = QtWidgets.QWidget()
    ui = Ui_GTM_Form()
    ui.setupUi(GTM_Form)
    GTM_Form.show()
    sys.exit(app.exec_())
Sirius3
User
Beiträge: 7777
Registriert: Sonntag 21. Oktober 2012, 17:20

Freitag 6. Oktober 2017, 12:16

@QTim: Bei QT verwendet man normalerweise vom ui-Designer generierte ui-Dateien statt die Widgets mit Python-Code zu erzeugen. Alles was nach `if __name__ ...` steht sollte in eine Funktion mit dem Namen main wandern, dann würde auch auffallen, dass in Zeile 23 GTM_Form nicht definiert ist.
Wenn also die Klasse Ui_GTM_Form wegfällt, mußt Du eine GTM_Form-Klasse schreiben, die Deinen anwendungsspezifischen Code enthält. Da wird es dann auch schwerm den Fehler, den Du jetzt hast, nochmal zu machen.
QTim
User
Beiträge: 7
Registriert: Mittwoch 27. September 2017, 08:58

Freitag 6. Oktober 2017, 12:59

@Sirius3

Ich habe das nicht alles von Hand programmiert, das wurde alles im Designer erstellt und dann mit dem Ui Konverter umgewandelt.
Am Ende möchte ich noch fertigen Pyhton Code einfügen welcher mir live Messdaten liefert, deswegen die Konvertierung.

In Zeile 23 ist GTM_Form nicht definiert, aber da wird es doch benötigt oder etwa nicht?
Wenn ich es weglasse bekomme ich folgenden Error:
TypeError: setupUi() missing 1 required positional argument: 'GTM_Form'
Sirius3
User
Beiträge: 7777
Registriert: Sonntag 21. Oktober 2012, 17:20

Freitag 6. Oktober 2017, 13:04

@QTim: genau das ist Dein Fehler. Du solltest die ui-Datei nicht konvertieren, sondern per loadui laden. Das, was da an ui-Code erzeugt wird, ist nicht dazu gedacht, das man das per Hand bearbeitet. Die Suche nach "loadui" hier im Forum findet genug Beispiele, wie solch ein QT-Programm aussehen sollte.
QTim
User
Beiträge: 7
Registriert: Mittwoch 27. September 2017, 08:58

Freitag 6. Oktober 2017, 13:31

Okay, danke für den Tipp! Ich werds mal versuchen. Soll man das so machen, dass man die Gui nicht zerschießt? :D
__deets__
User
Beiträge: 2847
Registriert: Mittwoch 14. Oktober 2015, 14:29

Freitag 6. Oktober 2017, 13:52

Im weitesten Sinne, ja. Theoretisch kann man natuerlich den generierten Code verwenden, wenn man wuesste, das sich der nicht mehr aendert. Die Erfahrung zeigt aber: tut er eigentlich immer. Das heisst, das man dann ploetzlich vor dem Problem steht, dass man neuen generierten Code und eigene Veraenderungen nicht mehr zusammen geschmissen bekommt.

Darum ist es besser gleich so zu arbeiten, dass man den generierten Code in Ruhe laesst (bzw im Fall von pyqt einfach den loader verwendet), und ihn so aufbaut, das man zB durch gut benannte Widgets sich eine Schnittstelle zum Rest des Programms schafft. Dann macht es nichts mehr, wenn man Dinge durcheinander wuerfelt.
Antworten