Unbekannte Probleme mit ListWidgets, Initialisierungproblem?

Python und das Qt-Toolkit, erstellen von GUIs mittels des Qt-Designers.
Antworten
sublist
User
Beiträge: 33
Registriert: Donnerstag 11. Dezember 2008, 16:04

Hi Leute.

Ich versuche zum ersten Mal ein UI mit QT zu basteln.
Das ganze soll in Maya 2012 laufen.
Leider bin ich auch mit OOP Programmierung etwas überfordert. Also nich gleich draufhauen ;)

Nun zum Problem:
Meine Liste funktioniert unter best. Bedingungen. Und das ist auch gleichzeitig mein Problem.
Ich glaub ich habe irgendwie ein Initialisierungsproblem.

Wenn ich den Code wie unten ausführe funktioniert nichts. Kein UI wird angezeigt

Code: Alles auswählen

import re
from pymel.core import *
from PyQt4 import QtGui, QtCore, uic

ui_filename = 'c:/Users/xxx/Google Drive/Coding/PYTHON/QT/HighScoreList.ui' #pfade checken!!!
logFile = internalVar(uad=True) + 'scriptEditorLogFile.txt'
form_class, base_class = uic.loadUiType(ui_filename)

#Interface Class
class Interface(base_class, form_class):
    def __init__(self):
        super(base_class, self).__init__()
        self.setupUi(self)
        self.setObjectName('Highscorelist')
        self.setDockNestingEnabled(True)
        self.Establish_Connections()

    #Checkboxes
    def recordBox_fn(self, state):
        if state == 0:
            toggleRecording()
            print('logging disabled')
        else:
            toggleRecording(1)
            print('logging enabled')

    def echoAllBox_fn(self, state):
        if state == 0:
            echoAllCommands()
            print('echo all OFF')
        else:
            echoAllCommands(1)
            print('echo all ON')

    def includeSelectBox_fn(self, state):
        if state == 0:
            print('disabled')
        else:
            print('enabled')

    #Button
    def logFileBtn_fn(self):
        print('Logfile cleared')
        global logFile
        open(logFile, "w").close()

    def debugBtn_fn(self):
        print('\n')
        outPutInfos(1,1)
        
    def Establish_Connections(self):
        #checkboxes
        self.recordBox.stateChanged.connect(self.recordBox_fn)
        self.echoAllBox.stateChanged.connect(self.echoAllBox_fn)
        self.includeSelectBox.stateChanged.connect(self.includeSelectBox_fn)
        #buttons
        self.logFileBtn.clicked.connect(self.logFileBtn_fn)
        self.debugBtn.clicked.connect(self.debugBtn_fn)
        
    def listWidget(self, listData = []):
        self.myList.clear()
        for i in range(0,len(listData),1):
            item = QtGui.QListWidgetItem(self.myList)
            item.setText(listData[i])

#Main
def main():
    global ui
    ui = Interface()
    ui.background.setPixmap(QtGui.QPixmap('c:/Users/gneumann/Google Drive/Coding/PYTHON/QT/logo_dummy.jpg')) #Add Image to Object "Background"
    ui.listWidget() #init
    listData = outPutInfos(1,1)
    ui.listWidget(listData)
    ui.show()

    # Make Window dockable
    '''
    if dockControl('ui_dock', q=1, ex=1):
        deleteUI('ui_dock')
    floatingLayout = paneLayout(configuration='single', width=213) #Size of Main Window
    allowedAreas = ['left', 'right']
    docControl = dockControl('ui_dock', area=allowedAreas[1], content=floatingLayout, label='Highscorelist')
    control('Highscorelist', e=True, p=floatingLayout)
    '''
Kommentiere ich die Zeilen aus, in denen ich das ListWidget befülle, wird das UI angezeigt

Code: Alles auswählen

listData = outPutInfos(1,1)
ui.listWidget(listData)
Starte ich danach wieder den original Code wird auch das UI mit neuem Inhalt gestartet.

Igendwie funktioniert wohl das befüllen und anzeigen in einem Schritt nicht :roll:

Hat jemand ne Idee was ich falsch mache?

Danke für eure Tips! :)
Zuletzt geändert von Hyperion am Donnerstag 31. Mai 2012, 12:07, insgesamt 1-mal geändert.
Grund: Code in Python-Code Tags gesetzt.
BlackJack

@sublist: Die Fehlerbeschreibung klingt seltsam. Wenn Du den Code startest wird nichts angezeigt, aber wenn Du die beiden besagten Zeilen auskommentierst wird die UI angezeigt und wenn Du *danach* das ganze noch einmal mit den beiden Zeilen startest wird die UI auch angezeigt‽ Das würde bedeuten es gäbe da eine Art „Gedächtnis” zwischen den Aufrufen, was eigentlich nicht sein kann. Es sei denn da läuft irgend etwas bei Maya quer.

Eventuell hast Du ein Problem mit dem `QListWidgetItem` mit dem `ListWidget`-Exemplar als Argument wenn die das Listenmodell sortiert ist. Sagt jedenfalls die Dokumentation zu `QListWidgetItem()`. Befolge den Rat dort vielleicht mal. Vielleicht war es das ja schon.

Sonstige Anmerkungen zum Quelltext:

Sternchenimporte machen ein Programm unübersichtlich. Man kann dann nicht mehr einfach nachvollziehen wo ein Name her kommt. Ausnahmen sind Module deren Dokumentation sagt, dass sie explizit für einen Sternchenimport geschrieben wurden, oder solche wo die Objekte so benannt sind, das man ihre Herkunft trotzdem erkennt. Beispiel für ersteres ist das `pygame.locals`-Modul und für letzteres die Qt-Module. Durch den `Q`-Präfix weiss man wo ein Objekt herkommt und dass man in der Qt-Dokumentation im Index nachschlagen kann.

Die Namensgebung ist sehr inkonsistent. Man hat bei den meisten GUI-Toolkits das Problem, dass man mit dem Style Guide for Python Code (a.k.a. PEP 8) brechen muss, aber Deine Namen halten sich zum Teil weder an die Python- noch an die Qt-Konventionen. Ich versuche aus der Situation immer das Beste zu machen, in dem ich bei der Programmlogik PEP 8 verwende und für GUI-Code die Konventionen des GUI-Toolkits. Das kann helfen GUI und Logik sauber zu trennen.

Auch semantisch sind die Namen teilweise nicht so gut benannt. Ein Name sollte eine Bedeutung des Objekts verraten, nicht hauptsächlich seinen Typ. Die Rückruffunktionen für die Checkboxen zum Beispiel sollten den `Box_fn`-Postfix verlieren und davor einen Namen bekommen der beschreibt was die Methode macht. Zum Beispiel `setRecordState()` statt `recordBox_fn()`. Ähnliches gilt auch für die anderen `_fn()`\s. Beispielsweise `clearLogFile()` statt des kryptischen `logFileBtn_fn()`.

Pfade sollte man nicht mit ``+`` sondern mit `os.path.join()` zusammen setzen. Der absolute Pfad zu der ``*.ui``-Datei ist unpraktisch.

Bei den Checkbox-Funktionen würde ich den Umstand nutzen, dass 0 und 1 einen Wahrheitswert haben und da keine expliziten Vergleiche schreiben und auch das sie Unterklassen von `bool` sind und die Konstanten `True` und `False` auch als Zahlen 1 und 0 angesehen werden. Das macht den Quelltext verständlicher. Ausserdem vermute ich mal, dass die Funktionen die da aufgerufen werden, auch mit 0 oder `False` im ersten Fall aufgerufen werden können — dann wäre der Quelltext unnötig lang und unsymmetrisch, denn dann könnte man den Funktionsaufruf aus den beiden Zweigen heraus ziehen. Mal exemplarisch:

Code: Alles auswählen

    def setFooState(self, state):
        set_foo_state(state)
        print('foo ' + ('enabled' if state else 'disabled'))
``global`` ist noch böser™ als Sternchenimport. Das sollte man aus seinem Wortschatz am besten streichen. Zumal es an beiden Stellen in Deinem Quelltext unnötig scheint.

Die Schleife in der `listWidget()` ist „unpythonisch”. Du benötigst den Index ja nicht ausser zum Indexieren in `listData`. Damit hast Du a) eine unnötige Variable und Indirektion und b) funktioniert die Methode nicht beliebigen iterierbaren Objekten, sondern nur mit Sequenzen. Man kann in Python *direkt* über die Elemente von Sequenzen iterieren, ohne einen Umweg über einen Index:

Code: Alles auswählen

    def replaceMyListContent(self, texts=()):
        self.myList.clear()
        for text in texts:
            item = QtGui.QListWidgetItem(self.myList)
            item.setText(text)
Wenn man Index *und* Element benötigt, gibt es die `enumerate()`-Funktion.
Antworten