如何将 PyQt5 QtWidgets.QTabWidget() 正确添加到子类 QWidget

How to add PyQt5 QtWidgets.QTabWidget() properly to sub-classed QWidget

我正在尝试子类化 PyQt5 QWidget 并封装 QTabWidget() 以进行动态重用,并且 运行 遇到选项卡不显示或显示但内容不显示的问题。

我想我一定是遗漏了一些基本的东西,而且我对 Qt 还很陌生。

这是我无法正确显示内容的示例代码。

import sys
import os
from PyQt5 import QtCore, QtGui, QtWidgets

scriptDir = os.path.dirname(os.path.realpath(__file__))          
testImage = scriptDir + os.path.sep + 'test_tree.png'

class TabImages(QtWidgets.QWidget):        
    def __init__(self, parent):   
        super(QtWidgets.QWidget, self).__init__(parent) 
        self.container = QtWidgets.QVBoxLayout()

        # Initialize tab screen
        self.tabs = QtWidgets.QTabWidget()
        self.tab1 = QtWidgets.QWidget()
        self.tab2 = QtWidgets.QWidget()
        self.tab3 = QtWidgets.QWidget()

        self.tab1_layout = QtWidgets.QVBoxLayout()  
        self.tab2_layout = QtWidgets.QVBoxLayout()  
        self.tab3_layout = QtWidgets.QVBoxLayout()

        self.tab1.setLayout(self.tab1_layout)
        self.tab2.setLayout(self.tab2_layout)
        self.tab3.setLayout(self.tab3_layout)

        self.tab1_label = QtWidgets.QLabel()
        self.tab2_label = QtWidgets.QLabel()
        self.tab3_label = QtWidgets.QLabel()

        self.tab1_pixMap =  QtGui.QPixmap(scriptDir + os.path.sep + 'test_image1.png')
        self.tab2_pixMap =  QtGui.QPixmap(scriptDir + os.path.sep + 'test_image2.png')
        self.tab3_pixMap =  QtGui.QPixmap(scriptDir + os.path.sep + 'test_image3.png')                

        self.tab1_label.setPixmap(self.tab1_pixMap)
        self.tab2_label.setPixmap(self.tab2_pixMap)
        self.tab3_label.setPixmap(self.tab3_pixMap)

        self.tab1_layout.addWidget(self.tab1_label)
        self.tab2_layout.addWidget(self.tab2_label)
        self.tab3_layout.addWidget(self.tab3_label)                         

        # Add tabs
        self.tabs.addTab(self.tab1,"Tab 1")
        self.tabs.addTab(self.tab2,"Tab 2")
        self.tabs.addTab(self.tab3,"Tab 3")  


        self.container.addWidget(self.tabs)
        #self.tabs.show()

class Main(QtWidgets.QMainWindow): 
    def __init__(self):
        super().__init__()
        self.title = 'Tabbed PixMap'
        self.left = 0
        self.top = 0
        self.width = 800
        self.height = 600
        self.setWindowTitle(self.title)
        self.setGeometry(self.left, self.top, self.width, self.height)               

        self.tabImages = TabImages(self)
        self.layout = QtWidgets.QVBoxLayout()        
        self.layout.addWidget(self.tabImages)
        #self.layout.addLayout(self.tabImages.container)

        self.center()
        self.show()

    def center(self):
        frameGm = self.frameGeometry()
        screen = QtWidgets.QApplication.desktop().screenNumber(QtWidgets.QApplication.desktop().cursor().pos())
        centerPoint = QtWidgets.QApplication.desktop().screenGeometry(screen).center()
        frameGm.moveCenter(centerPoint)
        self.move(frameGm.topLeft())

if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    main = Main()
    sys.exit(app.exec_())

注意注释掉的部分

tabs.show()

如果我取消注释,选项卡容器会显示但在主 window.

之外

我也尝试过同时添加布局和小部件,但似乎都没有改变行为。我会很感激任何人的洞察力。

如果我在单个 window 中做同样的事情而不尝试将其子类化为新的小部件,那么我会这样做并使用 setCentralWidget() 并且它工作正常

import sys
import os
from PyQt5 import QtCore, QtGui, QtWidgets

scriptDir = os.path.dirname(os.path.realpath(__file__))          
testImage = scriptDir + os.path.sep + 'test_tree.png'



class Main(QtWidgets.QMainWindow): 
    def __init__(self):
        super().__init__()
        self.title = 'Tabbed PixMap'
        self.left = 0
        self.top = 0
        self.width = 800
        self.height = 600
        self.setWindowTitle(self.title)
        self.setGeometry(self.left, self.top, self.width, self.height)               

        # Initialize tab screen
        self.tabs = QtWidgets.QTabWidget()
        self.tab1 = QtWidgets.QWidget()
        self.tab2 = QtWidgets.QWidget()
        self.tab3 = QtWidgets.QWidget()

        self.tab1_layout = QtWidgets.QVBoxLayout()  
        self.tab2_layout = QtWidgets.QVBoxLayout()  
        self.tab3_layout = QtWidgets.QVBoxLayout()

        self.tab1.setLayout(self.tab1_layout)
        self.tab2.setLayout(self.tab2_layout)
        self.tab3.setLayout(self.tab3_layout)

        self.tab1_label = QtWidgets.QLabel()
        self.tab2_label = QtWidgets.QLabel()
        self.tab3_label = QtWidgets.QLabel()

        self.tab1_pixMap =  QtGui.QPixmap(scriptDir + os.path.sep + 'test_image1.png')
        self.tab2_pixMap =  QtGui.QPixmap(scriptDir + os.path.sep + 'test_image2.png')
        self.tab3_pixMap =  QtGui.QPixmap(scriptDir + os.path.sep + 'test_image3.png')                

        self.tab1_label.setPixmap(self.tab1_pixMap)
        self.tab2_label.setPixmap(self.tab2_pixMap)
        self.tab3_label.setPixmap(self.tab3_pixMap)

        self.tab1_layout.addWidget(self.tab1_label)
        self.tab2_layout.addWidget(self.tab2_label)
        self.tab3_layout.addWidget(self.tab3_label)

        # Add tabs
        self.tabs.addTab(self.tab1,"Tab 1")
        self.tabs.addTab(self.tab2,"Tab 2")
        self.tabs.addTab(self.tab3,"Tab 3")     

        self.setCentralWidget(self.tabs)
        self.center()
        self.show()


    def center(self):
        frameGm = self.frameGeometry()
        screen = QtWidgets.QApplication.desktop().screenNumber(QtWidgets.QApplication.desktop().cursor().pos())
        centerPoint = QtWidgets.QApplication.desktop().screenGeometry(screen).center()
        frameGm.moveCenter(centerPoint)
        self.move(frameGm.topLeft())

if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    main = Main()
    sys.exit(app.exec_())       

我不知道它有什么不同,但我正在 运行 在 windows 10 机器上使用 Anaconda 打包的 PyQT5 的重新编译版本。

谢谢

您的主要问题出现是因为:

  • 在第一张图片中 window 在 window 之外的原因之一是因为 self.container 从未被分配。

  • self.layout也是如此。

布局不是小部件,它不是图形元素,它只是一个 class 管理分配给分配给相同布局的小部件的小部件的位置和大小,因此,如果您不为特定小部件分配布局,这将不起作用。

在 self.layout 的情况下,我认为这是不必要的,因为你只有一个小部件:self.tabImages 这可以是中央小部件,如果你有更多小部件,你可以创建一个新的中央小部件, 为新的中央小部件分配一个布局,并在该布局中添加其他小部件。

import sys
import os
from PyQt5 import QtCore, QtGui, QtWidgets

scriptDir = os.path.dirname(os.path.realpath(__file__))          
testImage = os.path.join(scriptDir, 'test_tree.png')

class TabImages(QtWidgets.QWidget):        
    def __init__(self, parent=None):   
        super(QtWidgets.QWidget, self).__init__(parent) 
        self.container = QtWidgets.QVBoxLayout(self)

        # Initialize tab screen
        self.tabs = QtWidgets.QTabWidget()
        self.tab1 = QtWidgets.QWidget()
        self.tab2 = QtWidgets.QWidget()
        self.tab3 = QtWidgets.QWidget()

        self.tab1_layout = QtWidgets.QVBoxLayout()  
        self.tab2_layout = QtWidgets.QVBoxLayout()  
        self.tab3_layout = QtWidgets.QVBoxLayout()

        self.tab1.setLayout(self.tab1_layout)
        self.tab2.setLayout(self.tab2_layout)
        self.tab3.setLayout(self.tab3_layout)

        self.tab1_label = QtWidgets.QLabel()
        self.tab2_label = QtWidgets.QLabel()
        self.tab3_label = QtWidgets.QLabel()

        self.tab1_pixMap =  QtGui.QPixmap(os.path.join(scriptDir, 'test_image1.png'))
        self.tab2_pixMap =  QtGui.QPixmap(os.path.join(scriptDir, 'test_image2.png'))
        self.tab3_pixMap =  QtGui.QPixmap(os.path.join(scriptDir,'test_image3.png'))            

        self.tab1_label.setPixmap(self.tab1_pixMap)
        self.tab2_label.setPixmap(self.tab2_pixMap)
        self.tab3_label.setPixmap(self.tab3_pixMap)

        self.tab1_layout.addWidget(self.tab1_label)
        self.tab2_layout.addWidget(self.tab2_label)
        self.tab3_layout.addWidget(self.tab3_label)                         

        # Add tabs
        self.tabs.addTab(self.tab1,"Tab 1")
        self.tabs.addTab(self.tab2,"Tab 2")
        self.tabs.addTab(self.tab3,"Tab 3")  
        self.container.addWidget(self.tabs)

class Main(QtWidgets.QMainWindow): 
    def __init__(self):
        super().__init__()
        self.title = 'Tabbed PixMap'
        self.left = 0
        self.top = 0
        self.width = 800
        self.height = 600
        self.setWindowTitle(self.title)
        self.setGeometry(self.left, self.top, self.width, self.height)               

        self.tabImages = TabImages()
        self.setCentralWidget(self.tabImages)

        self.center()
        self.show()

    def center(self):
        frameGm = self.frameGeometry()
        screen = QtWidgets.QApplication.desktop().screenNumber(QtWidgets.QApplication.desktop().cursor().pos())
        centerPoint = QtWidgets.QApplication.desktop().screenGeometry(screen).center()
        frameGm.moveCenter(centerPoint)
        self.move(frameGm.topLeft())

if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    main = Main()
    sys.exit(app.exec_())