QTabWidget

Python und das Qt-Toolkit, erstellen von GUIs mittels des Qt-Designers.
Antworten
eckipy
User
Beiträge: 6
Registriert: Samstag 26. Januar 2019, 17:40

Hallo,
da dieses mein erster Beitrag ist, möchte ich kurznsagen, das schon dem alten Semester angehöre. Vor Jahren habe ich mal mit VB etwas programmiert und danach eigentlicht lange nichts mehr gemacht. Ich arbeite in der Behinderten Arbeit. Da ist es so, das die lieben Menschen, die ich betreuen darf, nicht lesen können. Deshalb möchten wir jetzt verschiedene Informationen für sie visualisieren. Mein Sohn hat mir empfohlen, das mit dem ResberryPi zu machen, deshalb bin ich auf Python gekommen.
Es geht darum, verschiedene Sachen zu visualisieren, deshalb möchte ich das mit einem QTabWidget machen. Jetzt habe ich 2 tabs erstellt. Im ersten Tab wird unser
Dienstplan gezeigt, das funktioniert sehr gut.

Auf dem 2. Tab möchte ich jetzt ein Label anzeigen, aber da passiert überhaupt nichts. Den Qellcode habe ich aus einem Beispiel zum QTabWidget und habedaran dann weiter gearbeitet. Hier ist der Beispiel Code. In den letzten 4 Zeilen versuche ich den 2. Tab zu benutzen. Es wäre sehr nett, wenn Ihr Euch das einmal ansehen könntet, und mir vielleicht sagen könntet, was da falsch ist. Vielleicht sehe ich auchgerade den Wald vor Bäumen nicht mehr, denn ich sitze seit gestern dran und versuch es irgendwie hinzukriegen.

Code: Alles auswählen

if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    
    

    wid = QtWidgets.QWidget()
    grid = QtWidgets.QGridLayout(wid)
    wid.setLayout(grid)
    
    
    
    # setting the inner widget and layout
    grid_inner = QtWidgets.QGridLayout(wid)
    wid_inner = QtWidgets.QWidget(wid)
    wid_inner.setLayout(grid_inner)
    
    # add the inner widget to the outer layout
    grid.addWidget(wid_inner)
    
    # add tab frame to widget
    wid_inner.tab = QtWidgets.QTabWidget(wid_inner)
    grid_inner.addWidget(wid_inner.tab)
    
    # create tab
    new_tab = QtWidgets.QWidget(wid_inner.tab)
    grid_tab = QtWidgets.QGridLayout(new_tab)
    grid_tab.setSpacing(10)
    new_tab.setLayout(grid_tab)
    new_tab.tab_name_private = "Dienstplan"
    wid_inner.tab.addTab(new_tab, "Dienstplan")
    
    # create tab 2
    new_tab2 = QtWidgets.QWidget(wid_inner.tab)
    new_tab2.setLayout(grid_tab)
    wid_inner.tab.addTab(new_tab2, "TimeTimer")
    
    grid = QtWidgets.QGridLayout()
    grid.setVerticalSpacing(0)
    new_tab.setLayout(grid) 
    
    grid2 = QtWidgets.QGridLayout()
    grid2.setVerticalSpacing(0)    
    new_tab2.setLayout(grid2)
    
   
    lbl_tab2 = QLabel("Test")
    symbol = os.path.join("Symbole", "spaetschicht.png")
    lbl_tab2.set_labelopt(symbol,QColor(255,0,0))
    
    grid2.addWidget(lbl_tab2,0,0)
Vielen Dank für Eure Hilfe!

Eckhard!
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@eckipy: Das ist nicht lauffähig, da fehlen ja mindestens mal die Import-Zeilen und am Ende dann auch der Aufruf der Qt-Hauptschleife.

Der Code sollte auch nicht einfach so auf Modulebene Variablen anlegen sondern in einer Funktion stehen. Die Hauptfunktion heisst üblicherweise `main()` und wird von da aus aufgerufen, wo Du gerade diesen ganzen Code stehen hast.

Die Namen sind fast durchweg schröcklich. Bitte keine Abkürzungen oder durchnummerierte Namen. Wenn es geht dann auch keine zu generischen Namen wenn dafür sinnvolle finden kann. `new_tab` hiesse beispielsweise besser `service_schedule_tab` oder `roster_tab`. Der Leser will ja nicht wissen das der Tab ”neu” ist, oder nur das es ein Tab ist, sondern was der konkret für eine Bedeutung für das Programm hat.

Das da neue Attribute an Qt-Objekte geheftet werden, ist unübersichtlich. Das kann man machen wenn man sich in einer `__init__()`-Methode befindet und die auf dem Objekt selbst setzt, da vermutet und findet das ein Leser auch, aber nicht einfach so auf Objekten von aussen.

`__init__()` wäre dann das Stichwort für objektorientierte Programmierung (OOP): So ziemlich jedes nicht-triviale GUI-Programm braucht das wenn es verständlich bleiben soll.

Last but not least: Wenn möglich würde ich den Code für das erstellen der GUI in Datendateien auslagern die mit dem GUI-Designer von Qt erstellt wurden und die dann im Programm laden.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
eckipy
User
Beiträge: 6
Registriert: Samstag 26. Januar 2019, 17:40

Hallo _blackjack_,

vielen Dank, das Du Dir den Ausschnitt angesehen hast.

Das das so nicht läuft, ist mir schon bewußt. Es geht mir nur darum, zu erfahren, warum im Tab 2 das Label nicht angezeigt wird. Welchen Fehler ich nicht finde.

Das bau alles auf ein Code-Beispiel auf, das ich im Netz gefunden habe. Vielleicht ist der Fehler ja einfacher zu finden, wenn ich "Mein Problem" mal direkt in das Beispiell einbaue. Das sieht dann so aus:

Code: Alles auswählen

# -'''- coding: utf-8 -'''-

import sys
from PySide2 import QtGui
from PySide2 import QtWidgets, QtCore
from PySide2.QtGui import QPainter, QColor

lbl = []

class MyLabel(QtWidgets.QLabel):
    def __init__(self, parent=None, text = "", farbe = QColor() ):
        super(MyLabel, self).__init__(parent=parent, )
        self.setText('Push Me')
        self.setAutoFillBackground(True)
        self.setStyleSheet('* { background-color: '+ QColor.name(farbe) + ' }')
        self.text = text
        self.farbe = farbe
    
        
    def paintEvent(self, paintEvent):
        painter = QPainter(self)
        pix = QtGui.QPixmap(self.text)
        h = self.height()-20
        w = self.width()-20
        painter.drawPixmap(10,10,w,h,pix)
        
    
    
    
   
    

if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    
    

    wid = QtWidgets.QWidget()
    grid = QtWidgets.QGridLayout(wid)
    wid.setLayout(grid)
    
    # setting the inner widget and layout
    grid_inner = QtWidgets.QGridLayout(wid)
    wid_inner = QtWidgets.QWidget(wid)
    wid_inner.setLayout(grid_inner)
    
    # add the inner widget to the outer layout
    grid.addWidget(wid_inner)
    
    # add tab frame to widget
    wid_inner.tab = QtWidgets.QTabWidget(wid_inner)
    grid_inner.addWidget(wid_inner.tab)
    
    # create tab
    new_tab = QtWidgets.QWidget(wid_inner.tab)
    grid_tab = QtWidgets.QGridLayout(new_tab)
    grid_tab.setSpacing(10)
    new_tab.setLayout(grid_tab)
    new_tab.tab_name_private = "test1"
    wid_inner.tab.addTab(new_tab, "test1")
    
    # create tab 2
    new_tab2 = QtWidgets.QWidget(wid_inner.tab)
    new_tab2.setLayout(grid_tab)
    wid_inner.tab.addTab(new_tab2, "test2")
    
    grid = QtWidgets.QGridLayout()
    grid.setVerticalSpacing(0)
   
    
    text = "Monk, Adrian"
    
    
    lbl = MyLabel(text = text, farbe = QColor(255,0,0))
    grid.addWidget(lbl,0,0)
    new_tab.setLayout(grid)
    
    
    grid2 = QtWidgets.QGridLayout()
    grid2.setVerticalSpacing(0)
    lbl2 = MyLabel(text = text, farbe = QColor(255,0,0))
    grid2.addWidget(lbl2,0,0)
    new_tab.setLayout(grid2)    
    
    
    wid.show()
    wid.resize(700,700)
    app.exec_()
MyLabel und die Sachen mit "grid2" habe ich eingebaut.

Auch bei diesem vereinfachten beispiel wird in Tab 2 kein Label angezeit.

LG
Eckhard!
eckipy
User
Beiträge: 6
Registriert: Samstag 26. Januar 2019, 17:40

Hallo,

einen Fehler habe ich gerade selbst noch gefunden..

Code: Alles auswählen

new_tab2.setLayout(grid2)   
LG
Eckhard!
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@eckipy: Du rufst auf jeden Fall zu oft `setLayout()` auf. Selbst mit der Änderung gibt es mindestens ein Widget bei dem Du versuchst einem Widget was bereits ein Layout hat, ein weiteres zu verpassen.

Schreib mal eine Funktion in der ein Tab hinzugefügt wird. Vielleicht siehst Du dann ja das Problem, bzw. hast es nicht mehr.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
eckipy
User
Beiträge: 6
Registriert: Samstag 26. Januar 2019, 17:40

Hallo _blackjack_

ich habe es mal mit weniger layouts verucht - sieht jetzt so aus

Code: Alles auswählen

# -'''- coding: utf-8 -'''-

import sys
from PySide2 import QtGui
from PySide2 import QtWidgets, QtCore
from PySide2.QtGui import QPainter, QColor

lbl = []

class MyLabel(QtWidgets.QLabel):
    def __init__(self, parent=None, text = "", farbe = QColor() ):
        super(MyLabel, self).__init__(parent=parent, )
        self.setText('Push Me')
        self.setAutoFillBackground(True)
        self.setStyleSheet('* { background-color: '+ QColor.name(farbe) + ' }')
        self.text = text
        self.farbe = farbe
    
        
    def paintEvent(self, paintEvent):
        painter = QPainter(self)
        pix = QtGui.QPixmap(self.text)
        h = self.height()-20
        w = self.width()-20
        painter.drawPixmap(10,10,w,h,pix)
        
    
    
    
   
    

if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    
    

    wid = QtWidgets.QWidget()
    grid = QtWidgets.QGridLayout(wid)
    wid.setLayout(grid)
    
    # setting the inner widget and layout
    grid_inner = QtWidgets.QGridLayout(wid)
    wid_inner = QtWidgets.QWidget(wid)
    wid_inner.setLayout(grid_inner)
    
    # add the inner widget to the outer layout
    grid.addWidget(wid_inner)
    
    # add tab frame to widget
    wid_inner.tab = QtWidgets.QTabWidget(wid_inner)
    grid_inner.addWidget(wid_inner.tab)
    
    # create tab
    new_tab = QtWidgets.QWidget(wid_inner.tab)
    grid_tab = QtWidgets.QGridLayout(new_tab)
    grid_tab.setSpacing(10)
    #new_tab.setLayout(grid_tab)
    new_tab.tab_name_private = "test1"
    wid_inner.tab.addTab(new_tab, "test1")
    
    # create tab 2
    new_tab2 = QtWidgets.QWidget(wid_inner.tab)
    new_tab2.setLayout(grid_tab)
    wid_inner.tab.addTab(new_tab2, "test2")
    
    text = "Monk, Adrian"
    
    
    lbl = MyLabel(text = text, farbe = QColor(255,0,0))
    grid_tab.addWidget(lbl,0,0)
    new_tab.setLayout(grid_tab)
    
    
    grid_tab2 = QtWidgets.QGridLayout()
    grid_tab2.setVerticalSpacing(0)
    lbl2 = MyLabel(text = text, farbe = QColor(255,0,0))
    grid_tab2.addWidget(lbl2,0,0)
    new_tab2.setLayout(grid_tab2)    
    
    lbl3 = MyLabel(text = text, farbe = QColor(0,255,0))
    grid_tab2.addWidget(lbl3)
    
    wid.show()
    wid.resize(700,700)
    app.exec_()
und funktioniert....

Ich hoffe, jetzt komme ich in meinem script auch weiter.

Vielen Dank!

Eckhard!
Antworten