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

Python 如何将PyQt5 QtWidgets.QTabWidget()正确添加到子类QWidget,python,qt5,pyqt5,qtabwidget,Python,Qt5,Pyqt5,Qtabwidget,我试图将PyQt5 QWidget子类化并封装一个QTabWidget(),以便动态重用,但遇到了一个问题,即选项卡不显示,或者它们确实显示,但其内容不显示 我想我一定是错过了一些基本的东西,而且我对Qt还相当陌生 下面是我无法正确显示的示例代码 import sys import os from PyQt5 import QtCore, QtGui, QtWidgets scriptDir = os.path.dirname(os.path.realpath(__file__))

我试图将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()
如果我取消注释,选项卡容器将显示在主窗口之外

我也尝试过添加布局和小部件,但两者似乎都没有改变行为。我将感谢任何人的洞察力

如果我在一个窗口中做同样的事情,而不尝试将子类化为一个新的小部件,那么我就这样做,并使用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机器上运行重新编译的PyQT5版本,该版本与Anaconda一起打包


谢谢

您的主要问题是因为:

  • 在第一个图像中,窗口位于窗口外部的原因之一是从未分配过
    self.container

  • 同样的情况也发生在
    self.layout

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

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

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_())

请注意,您的问题与子类化无关。您需要在小部件中添加一些描述,然后将
QTabWidget
添加到该布局中。我无法理解您想知道什么。如何在标题中正确地对QTabWidget进行子类化,但请告诉我们您希望的结果。或者您想知道布局系统setCentralWidget,父子关系呢?对不起,我想我在子类小部件中已经有了一个布局(self.container),并且我已经正确地将QTab添加到了这个布局中。我成功地使用了QTabWidget,但没有将其封装在子类widget中,因此我的问题似乎出现在具体的实现中。我还通过addWidget()和addLayout()使用其容器布局将subc classed widget对象添加到主窗口布局中,但两者都没有按预期的方式工作。@Dizzixx您了解什么是子类化吗?子类化对您来说是什么?子类化是我在代码顶部对TabImages类所做的。它通过行super(qtwidts.QWidget,self)继承了QWidget的方法。这应该允许我使用这个子类,就像我使用QWidget一样,通过重新定义它来覆盖它当前的功能,或者添加新的功能。在本例中,我通过在初始化时生成QTabWidget、选项卡、选项卡布局、选项卡内容和小部件布局,为默认初始化添加了功能。Eyllanesc感谢您的回复。我试图通过产生一个最小的问题来简化事情,这个问题展示了我所认为的问题所在。我实际上是在调试这个更通用的选项卡式小部件fddfdfd@Dizzixx嗯,你最好解释一下,我不明白你指的是什么。在你的问题中,你指出使用这个方法,我有一个单独的小部件,但是如果我使用一个方法,如果它可以工作,我怎么能使它工作子分类?这就是我的答案。如果你不在问题中指出,我不知道你的其他问题,所以我不感兴趣。总之,我的回答是否解决了您在当前问题中指出的问题?很抱歉,我不经常使用堆栈,我尝试使用代码进行注释,但它不起作用,然后我的注释编辑超时,无法修复上面的混乱。。。。。我马上回答。