0

So I'm lost ... again. I have a QMainWindow with a empty QStackedWidget. I would like to dynamically populate the QStackedWidget using a custom widget that I created in Qt Creator. I tried following Creating a custom widget in PyQT5 in another thread, but that doesn't really cover importing from a UI file in this case. I keep receiving:

AttributeError: 'QStackedWidget' object has no attribute 'addItemWidget'

Here is the code for the Widget...

# ItemWidget.py

from PyQt5 import uic
from PyQt5.QtWidgets import QWidget


class Widget:

    def __init__(self):
        self.text = None
        self.data = None


class ItemWidget(QWidget):

    def __init_(self, parent = None):
        self.WidgetList = []
        QWidget.__init__(self, parent = parent)
        uic.loadUi(r'interface/ItemWidget.ui', self)

    def addItemWidget(self, index, text):
        widget = Widget()
        widget.text = text
        self.WidgetList.append([])
        self.WidgetList[index].append(widget)

        # TESTING
        print(self.WidgetList)

Relevant code from main.py:

from ItemWidget import *

for key, value in self.ItemIndexList.items():
    self.ItemStackedWidget.addItemWidget(value, key)

I understand that I'm getting this error because QStackedWidget has no defined attribute called 'addItemWidget, but I don't know what I need to do to get this to work as intended. When I try overriding the method using 'addWidget', I get an unexpected value error.

Any ideas? I'm fairly new to Python and still learning, so if I'm missing some important information please let me know.

I have a few different revisions of my MainWindow.ui. One just has a QStackedWidget where I want the pages to go, the other is completely laid out how I would imagine the final product to look. The ItemWidget.ui file just contains the elements I want to add to each QStackedWidget page. I have not promoted any of them to a custom class, which I suspect I will need to do.

I'm currently using Python 3.6 and PyQt5

** EDIT TO ADD MVCE **

TestApp.py

from PyQt5.QtWidgets import QApplication
import TestMain
import sys


class MCVE(QApplication):

    def __init__(self):
        args = sys.argv
        QApplication.__init__(self, args)
        self.application = TestMain.TestMainWindow()

    def initApp(self):
        self.application.show()


if __name__ == '__main__':
    app = MCVE()
    app.initApp()
    sys.exit(app.exec_())

TestMain.py

from PyQt5.Qt import Qt
from PyQt5.QtWidgets import QMainWindow
from TestItemWidget import *


class TestMainWindow(QMainWindow):

    def __init__(self):
        QMainWindow.__init__(self, None, Qt.Window)
        uic.loadUi(r'interface/TestMainWindow.ui', self)

        SlotList = {('Header1', 0),('Header2', 1)}

        for key, value in SlotList:
            self.ItemStackedWidget.addItemWidget(value, key)

TestItemWidget.py

from PyQt5 import uic
from PyQt5.QtWidgets import QWidget


class Widget:

    def __init__(self):
        self.text = None
        self.data = None


class ItemWidget(QWidget):

    def __init_(self, parent = None):
        self.WidgetList = []
        QWidget.__init__(self, parent = parent, flags = None)
        uic.loadUi(r'interface/TestItemWidget.ui', self)

    def addItemWidget(self, index, text):
        widget = Widget()
        widget.text = text
        self.WidgetList.append([])
        self.WidgetList[index].append(widget)
        print(self.WidgetList)

if __name__ == '__main__':
    pass

TestItemWidget.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>Form</class>
 <widget class="QWidget" name="Form">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>400</width>
    <height>300</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>Form</string>
  </property>
  <layout class="QVBoxLayout" name="verticalLayout">
   <item alignment="Qt::AlignHCenter">
    <widget class="QLabel" name="label">
     <property name="text">
      <string>ItemWidget</string>
     </property>
    </widget>
   </item>
  </layout>
 </widget>
 <resources/>
 <connections/>
</ui>

TestMainWindow.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>MainWindow</class>
 <widget class="QMainWindow" name="MainWindow">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>417</width>
    <height>288</height>
   </rect>
  </property>
  <property name="MainWindowUI" stdset="0">
   <string>MainWindow</string>
  </property>
  <widget class="QWidget" name="widget">
   <layout class="QVBoxLayout">
    <item>
     <widget class="QStackedWidget" name="ItemStackedWidget"/>
    </item>
   </layout>
  </widget>
 </widget>
 <resources/>
 <connections/>
</ui>
4

1 回答 1

1

If you want to interact with a widget you must do it where the widget exists and in your case QStackedWidget exists in TestMain.py so you must use it with your addWidget method, it does not have the addItemWidget method, I also recommend verifying your syntax, for example the init method is placed with 2 underscores on each side, but in your code ItemWidget has only one on the right side: __init_, in conclusion your code should be as follows, add the text to the labels to make it visible:

TestMain.py

from PyQt5.Qt import Qt
from PyQt5.QtWidgets import QMainWindow, QMenu, QToolBar, QTreeWidgetItem
from TestItemWidget import *

class TestMainWindow(QMainWindow):
    def __init__(self):
        QMainWindow.__init__(self, None, Qt.Window)
        uic.loadUi(r'interface/TestMainWindow.ui', self)

        SlotList = {('Header1', 0),('Header2', 1)}

        for key, value in SlotList:
            w = ItemWidget(self)
            w.label.setText(key)
            self.ItemStackedWidget.insertWidget(value, w)

TestItemWidget.py

from PyQt5 import uic
from PyQt5.QtWidgets import QWidget

class ItemWidget(QWidget):
    def __init__(self, parent = None):
        QWidget.__init__(self, parent = parent)
        uic.loadUi(r'interface/TestItemWidget.ui', self)
于 2017-12-05T04:54:37.193 回答