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

时间:2018-08-20 14:06:46

标签: 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__))          
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()

如果我取消注释,则选项卡容器显示但在主窗口之外。

enter image description here

我也尝试添加布局和小部件,但似乎都没有改变行为。我将不胜感激任何人的见识。

如果我在单个窗口中执行相同的操作而没有尝试将其子类化为新的小部件,则可以这样做,并使用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_())       

enter image description here

我不知道这有什么不同,但是我正在Windows 10机器上运行与Anaconda打包在一起的PyQT5的重新编译版本。

谢谢

1 个答案:

答案 0 :(得分:2)

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

  • 在第一张图像中窗口位于窗口外部的原因之一是因为从未分配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_())