Seite 1 von 1

Funktion aus Klasse auslagern

Verfasst: Samstag 27. Dezember 2014, 21:50
von michpro
Hallo zusammen,

ich bin neu hier im Forum. Mein bisheriger Wissensstand habe ich mir selbst angeeignet. Deshalb entschuldigt wenn ich mich etwas unverständlich, verwirrend oder wie auch immer ausdrücke.

Jetzt aber zu meinem Problem.

Ich habe mit QT-Designer eine Gui Oberfläche erstellt, in der ich per Slider und PushButton einen Sollwert für Temperatur einstellen kann. Die Gui-Oberfläche habe ich in mein Python Script eingebunden. Über die Signale ValueChanged() und clicked() starte ich entsprechende Funktionen. Solange ich die Funktionen in der erstellten Klasse "MyWindow" starte funktioniert alles. Jetzt möchte ich aber die Funktion "#Funktion Solltemperatur übernehmen" aus der Klasse auslagern. Hier scheitere ich jedoch kläglich. :?

Hier mein Code:

Code: Alles auswählen

""" 
$Revision: 13 $
$URL: file://diskstation/svn/Python/TestPythonProjekte/trunk/GUI_Qt.py $
letzte Änderung:  $Date:: 2014-12-27 20:46:45 #$
----------------------------------------------------------------
Beschreibung:
 Python Script: erste Programmierversuche GUI mit pyQT

----------------------------------------------------------------
"""
# -*- coding: utf-8 -*-

#Import für Qt
import sys
from PyQt5 import QtWidgets, QtCore, uic


#Funktion Solltemperatur übernehmen
def functionSollTempUebernahme():
  Value=MyWindow().SliderSollTemp.value()
  print(str(Value))


class MyWindow(QtWidgets.QMainWindow):
  def __init__(self):
    super(MyWindow, self).__init__()
    uic.loadUi("MainWindowQt.ui", self)

    #Initalisieren Signal / Slots
    self.SliderSollTemp.valueChanged.connect(self.functionSollAenderung)
    self.pB_SollTempUeber.clicked.connect(functionSollTempUebernahme)

    #MainView anzeigen
    self.show()

  #Funktion Änderung Solltemperatur
  def functionSollAenderung(self):
    Value=self.SliderSollTemp.value()
    self.LcdSollTemp.display(Value)

#  #Funktion Solltemperatur übernehmen
#  def functionSollTempUebernahme(self):
#    Value=self.SliderSollTemp.value()
#    print(str(Value))

if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    window = MyWindow()
    sys.exit(app.exec_())


Ich hoffe Ihr könnt mir da etwas auf die Sprünge helfen.

DANKE!

Re: Funktion aus Klasse auslagern

Verfasst: Samstag 27. Dezember 2014, 22:12
von BlackJack
@michpro: Wenn man eine Klasse aufruft dann erstellt man ein Exemplar davon. `MyWindow` ist ein Qt-Fenster, wenn Du das also aufrufst erstellst Du ein neues Fenster-Objekt. Das willst Du in der Funktion ja aber gar nicht, sondern Du willst auf das bestehende Fenster zugreifen. Also müsstest Du das beim Aufruf als Argument übergeben. Das liesse sich beim `connect()`-Aufruf mit `functools.partial()` bewerkstelligen das man eine neue Funktion erstellt aus der vorhandenen `functionSollTempUebernahme()`-Funktion und dem Fenster-Objekt dessen `__init__()` gerade ausgeführt wird wenn `connect()` aufgerufen wird.

Aber warum willst Du so etwas machen wenn die Funktion doch ganz eindeutig gar keine allgemeine, eigenständige Funktion ist sondern auf die Daten in der Klasse zugreift und damit als Methode deutlich besser aufgehoben ist.

Die Einrücktiefe ist übrigens per Konvention vier Leerzeichen und nicht zwei. Und auch wenn sich die Qt-Anbindung an die Namenskonventionen vom C++-Projekt Qt hält möchte ich mal auf den Style Guide for Python Code hinweisen. Spätestens wenn man Funktionen schreibt die tatsächlich nichts mehr mit der GUI zu tun haben, würde ich zu den üblichen Python-Konventionen raten.

Edit: Und Funktions- und Methodennamen den Präfix `function` voranzustellen sollte man auch sein lassen. Funktionen und Methoden werden in der Regel nach Tätigkeiten benannt weil sie etwas *tun*. Das sollte genug sein um sie von anderen Werten unterscheiden zu können.

Re: Funktion aus Klasse auslagern

Verfasst: Samstag 27. Dezember 2014, 22:28
von Sirius3
@michpro: noch ergänzend zu dem was BlackJack bereits geschrieben hat, falls die Funktion "functionSollTempUebernahme" tatsächlich unabhängig von der GUI arbeiten kann, dann macht es keinen Sinn, die Abhängigkeit zum Slider in die Funktion hineinzuschreiben. Das Einzige was die Funktion braucht, ist ja die Soll-Temperatur. Eine sinnvolle Trennung sähe dann so aus:

Code: Alles auswählen

def soll_temperatur_uebernehmen(soll_temperatur):
    print(soll_temperatur)

[...]
        self.pB_SollTempUeber.clicked.connect(lambda: soll_temperatur_uebernehmen(self.SliderSollTemp.value()))
[...]
Eine Funktion function... zu nennen ist ein bißchen überflüssig, da wenn man sie aufruft ja erkennt, dass es eine Funktion ist.

Re: Funktion aus Klasse auslagern

Verfasst: Samstag 27. Dezember 2014, 22:38
von michpro
ok.. ich danke euch!
Werde also meine Funktionen umbenennen und alles in der Klasse lassen... ich dachte es wäre somit etwas übersichtlicher. Funktionell sicher kein Vorteil oder Nachteil. Da ich erst am Anfang von Python bin möchte ich auch einfach Dinge ausprobieren um Erfahrung zu sammeln.