如何将 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_())
我正在尝试子类化 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_())