dropdown Menu im QtableWidget

Python und das Qt-Toolkit, erstellen von GUIs mittels des Qt-Designers.
Antworten
Ernie1412
User
Beiträge: 161
Registriert: Freitag 10. Januar 2020, 20:38

ich habe eine json datei, die sieht wie folgt aus:

Code: Alles auswählen

    "puselmuckelside": {
        "Artist": {
            "Attri": "",
            "Single": 0,
            "XPath": "//div[@class='vdoCast']/a[contains(@href,'/model')]"
        },
        "Beschreibung": {
            "Attri": "",
            "Clicks": 0,
            "XPath": "//div[@class='vdoDesc']"
        },
                "Film": "",
        "NebenSide": {
            "Clicks": 0,
            "XPath": "//div[@class='vdoCast']/a[1]"
        },
        "NummerID": {
            "XPath": "//div[@class='thumbsHolder elipsTxt']/div/div[@class='echThumb']/a[contains(@id,'videos')]"
        },
        }
jetzt möchte ich diese nicht immer für jede Side von Hand verändern, sondern schön in eine Tabelle editierbar machen.
in der json hab ich ca. 40 puselpuckelsides :)
hier die Tabelle:

Code: Alles auswählen

def LoadJSON(self):   

        with open(Path(__file__).absolute().parent / "JSON/websides.json",'r') as file:
            websides = json.loads(file.read())
        side=self.lblWebside.text()
        try:
            web=websides[side]            
            for zeile,item in enumerate(web):                                
                try:
                    xpath=web[item]                                    
                    self.tblWdg_WebSides.setItem(zeile,0,QtWidgets.QTableWidgetItem(xpath['XPath']))
                    zustand=xpath.get("Attri")
                    if zustand is not None:
                        zustand=xpath["Attri"]
                        print(f"Attri: {zustand} bei {xpath}")
                        self.tblWdg_WebSides.setItem(zeile,1,QtWidgets.QTableWidgetItem(zustand))
                    zustand=xpath.get("Single")
                    if zustand is not None:
                        zustand=xpath["Single"]
                        if zustand==0:
                            zustand=True
                        else: zustand=False
                        print(f"Single: {zustand} bei {xpath}")                        
                        self.tblWdg_WebSides.setCellWidget(zeile,2,self.TrueFalse(zustand))               
                    zustand=xpath.get("Art")
                    if zustand is not None:
                        zustand=xpath["Art"]                        
                        print(f"Art: {zustand} bei {xpath}")
                        self.tblWdg_WebSides.setItem(zeile,3,QtWidgets.QTableWidgetItem(xpath[zustand]))
                    zustand=xpath.get("Gross")
                    if zustand is not None:
                        zustand=xpath["Gross"]                        
                        if zustand==0:
                            zustand=True
                        else: zustand=False
                        print(f"Gross: {zustand} bei {xpath}")
                        self.tblWdg_WebSides.setCellWidget(zeile,4,self.TrueFalse(zustand))
                    zustand=xpath.get("Click")
                    if zustand is not None:
                        zustand=xpath["Click"]
                        if zustand==0:
                            zustand=True
                        else: zustand=False
                        print(f"Click: {zustand} bei {xpath}")
                        self.tblWdg_WebSides.setCellWidget(zeile,5,self.TrueFalse(zustand))
                    zustand=xpath.get("Skip")
                    if zustand is not None:
                        zustand=xpath["Skip"]
                        if zustand==0:
                            zustand=True
                        else: zustand=False
                        print(f"Skip: {zustand} bei {xpath}")                        
                        self.tblWdg_WebSides.setCellWidget(zeile,6,self.TrueFalse(zustand)) 
                except TypeError:                    
                    self.tblWdg_WebSides.setItem(zeile,0,QtWidgets.QTableWidgetItem(web[item]))                          
        except KeyError:
            with open(Path(__file__).absolute().parent / "JSON/Arten.json",'r') as file:
                Arten = json.loads(file.read()) 
            self.tblWdg_WebSides.setRowCount(len(Arten["Arten"]))
            self.tblWdg_WebSides.setVerticalHeaderLabels(Arten["Arten"])
        self.tblWdg_WebSides.resizeColumnsToContents()

    def TrueFalse(self,zustand):
        selectItem = QtWidgets.QComboBox()
        selectItem.addItems(['True', 'False'])
        selectItem.setCurrentText(zustand)        
        return selectItem
1. er macht keine dropdown Menus in der Tabelle.
das mit selectItem habe ich von :https://www.programcreek.com/python/exa ... ableWidget
ich denke er hat ein Problem mit "self.tblWdg_WebSides.setCellWidget(zeile,6,self.TrueFalse(zustand))"
dann bekommt er ein TypeError und macht garnichts mehr, sprich keine Daten in der Tabelle.
auf programmcreek machen die das doch auch so:

Code: Alles auswählen

for i in range(length):
            imageItem = QTableWidgetItem(self.DataSetsHist[i])
            selectItem = QtWidgets.QComboBox()
            selectItem.addItems(['Training', 'Validation', 'Test'])
            self.table.setItem(i, 0, imageItem)
            self.table.setCellWidget(i, 1, selectItem)

Edit:
selectItem.setCurrentIndex(zustand)
und dieses

Code: Alles auswählen

 if zustand==0:
                            zustand=True
                        else: zustand=False

weggelassen
kommt schon mal ein dropdown
nur irgendwann keine daten mehr in der tabelle
Ernie1412
User
Beiträge: 161
Registriert: Freitag 10. Januar 2020, 20:38

ich habs nun:)
Ernie1412
User
Beiträge: 161
Registriert: Freitag 10. Januar 2020, 20:38

habs nochmal etwas verbessert:
anstatt try: nun "if isinstance(web[item], dict):"
Sirius3
User
Beiträge: 17737
Registriert: Sonntag 21. Oktober 2012, 17:20

Methoden und Variablennamen schreibt man komplett klein.
Man benutzt keine kryptischen Abkürzungen wie tbl oder wdg, das versteht ja keiner.
Wie viele Seiten hat eine Spinnennetz?
Path kennt read_text, bzw. read_bytes.
Wenn man eigentlich nur die Werte eines Wörterbuchs möchte, dann gibt es dafür values.
Nur ein Wert davon ist ein XPath, warum nennst Du die Variable dann xpath?
Mit dict.get bekommst Du schon den Wert, warum ermittelst Du den nochmal?
Wenn Du bei ›zustand == 0‹ doch nur wieder ein Boolean setzt, kannst Du doch die Bedingung gleich als Wert einsetzen.
Statt Code zu kopieren und leicht zu modifizieren, benutzt man Funktionen.
Das Lesen von Arten sollte wohl nicht per Exception erfolgen, sondern in einer extra Funktion.
Man sollte nicht so große try-Blöcke haben, sondern nur den Teil, wo der Fehler auftritt, hier aber am besten gar nicht per try.

Das ganze könnte dann ungefähr so aussehen:

Code: Alles auswählen

    WEBSITES_JSON_PATH = Path(__file__).absolute().parent / "JSON/websides.json"
    ARTEN_JSON_PATH = Path(__file__).absolute().parent / "JSON/Arten.json"

    def set_str_item(self, info, zeile, spalte, name):
        value = info.get(name)
        if value is not None:
            print(f"{name}: {value} bei {info}")
            self.table_websites.setItem(zeile, spalte, QtWidgets.QTableWidgetItem(value))

    def set_bool_item(self, info, zeile, spalte, name):
        value = info.get(name)
        if value is not None:
            print(f"{name}: {value} bei {info}")
            item = QtWidgets.QComboBox()
            item.addItems(['True', 'False'])
            item.setCurrentIndex(value)
            self.table_websites.setItem(zeile, spalte, item)

    def load_json(self):   
        websites = json.loads(self.JSON_PATH.read_bytes())
        site = self.label_website.text()
        website = websites.get(site)
        if website is not None:
            for zeile, info in enumerate(website.values()):
                self.set_str_item(info, zeile, 0, "XPath")
                self.set_str_item(info, zeile, 1, "Attri")
                self.set_bool_item(info, zeile, 2, "Single")
                self.set_str_item(info, zeile, 3, "Art")
                self.set_bool_item(info, zeile, 4, "Gross")
                self.set_bool_item(info, zeile, 5, "Click")
                self.set_bool_item(info, zeile, 6, "Skip")
        else:
            arten = json.loads(self.ARTEN_JSON_PATH.read_bytes())
            self.table_websites.setRowCount(len(arten["Arten"]))
            self.table_websites.setVerticalHeaderLabels(arten["Arten"])
        self.table_websites.resizeColumnsToContents()
Ernie1412
User
Beiträge: 161
Registriert: Freitag 10. Januar 2020, 20:38

dank dir Sirius3

einige Dinge waren mir neu wie "websites = json.loads(WEBSITES_JSON_PATH.read_bytes())"
daß das so einfach geht :)

ich muss wahrscheinlich mehr in funktionen denken, wie kann man gleiche Arbeiten in funktonen packen.
deine Methode ist nartürlich übersichtlicher als meine verschachtelten if Anweisungen und auch schneller hab ich das Gefühl, naja denke nicht das der i7-9700K da Probleme hat :)

einige kleine Fehlerchen hattest auch drin, aber wahrscheinlich konntest das script nicht mal testen.
wie:

Code: Alles auswählen

if isinstance(info,str):                    
                    self.set_str_item(info, zeile, 0, "")
                else: 
für nicht "Tags" (dicts) wie Xpath, Clicks usw. also strings wurden ohne diese if Anweisung geskipt.

aber so konnte ich auch besser die vorgehensweise verstehen.

Es ist wahrscheinlich auch Erfahrungssache, das mit den Funktionen, da muss ich definitv noch was lernen.
mit den Namen usw. werd ich versuschen auch zu beherzigen, obwohl bei pyqt5 Objekten das schlimm finde. ich mach die GUI ja mit den QT Designer.

hab hier zum erstenmal konkrete Hilfe bekommen. Danke !!
Ernie1412
User
Beiträge: 161
Registriert: Freitag 10. Januar 2020, 20:38

Wie erhalte ich die Werte der comboboxen in den Cells?
Das sind ja keine Cells mehr bzw die sind leer als Tabelle.
Bzw wie bekomme ich nun aus einer Combo wieder eine cell?
Item = qwidgets.qtablewidget() geht nicht.
Die Combo verschwindet wohl aber es wird keine Cell raus.
Da ist auch ein kleiner Rahmen nun drum.
Kann das sein das das eine Tabelle in eine Tabelle ist ? Und ich seh nur die obere Ecke?
Antworten