Python QTableWidget 不显示全角
Python QTableWidget not displaying full width
我是一位经验丰富的(如果有点生疏的话)Windows 程序员。我正在尝试创建我在 1963 年设计的计算机 (Ferranti Argus 400) 的部分逻辑模拟(是的,我就是那么老!
不过,我是 Python 编程的新手,在使用 QTableWidget 时遇到格式问题。
我想将其显示在右侧,旁边是一组控件,用于输入模拟功能的测试数据(并使用 QTableWidget 显示模拟将要执行的步骤 运行到)例如逐位显示乘法器的工作。
我正在尝试使用 QHBoxLayout() 作为带有两个嵌入框的外部容器。左侧的 QVBox 将包含我的模拟数据条目,右侧的框将包含 QTablewidget 对象,滚动显示计算机寄存器的状态。
QTableWidget 工作正常(下面的是一种简化),直到我在左侧添加一个包含控件的 Vbox(此处包含一组)。 Table 从其全宽缩小并将其自身定位在剩余 space 的右侧。我希望它位于其他控件的左侧,并在空间不足时滚动(目标机器有 32*24 位寄存器可以显示,尽管我最初将使用 8 位进行测试)
屏幕左侧有一个组
在此处输入图片描述
class App(QMainWindow):
def __init__(self):
super().__init__()
self.title = 'PyQt5 simple window'
self.left = 10
self.top = 50
self.width = 800
self.height = 480
self.initUI()
def initUI(self):
self.setWindowTitle(self.title)
self.setGeometry(self.left, self.top, self.width, self.height)
# Parent layout
self.central_Widget = QWidget(self)
self.setCentralWidget(self.central_Widget)
self.central_Layout = QHBoxLayout()
# Configure left panel as Vbox
self.leftpanel_Layout = QVBoxLayout()
#
self.leftpanel_Layout.addWidget(DataSelectionGroup("Data entry mode"))
#
# Add stretch to bottom of panel
self.leftpanel_Layout.addStretch(0)
self.rightpanel_Layout = QVBoxLayout()
self.myLogTable = LogTablex()
self.rightpanel_Layout.addWidget(self.myLogTable)
self.setLayout(self.rightpanel_Layout)
# Add left panel layout to central layout
# uncomment these lines to see the unwanted behaviour
#self.central_Layout.addLayout(self.leftpanel_Layout)
#self.central_Layout.addStretch(0)
self.setLayout(self.central_Layout)
self.central_Layout.addLayout(self.rightpanel_Layout)
self.setLayout(self.central_Layout)
self.central_Widget.setLayout(self.central_Layout)
self.setWindowTitle("Demo")
self.show()
class DataSelectionGroup(QGroupBox):
""" Create a group of Radio Buttons to choose type of data entry """
def __init__(self, title):
super().__init__(title)
self.buttonLayout = QVBoxLayout()
# add radio buttons to choose which mode of data entry to use
self.radio1 = QRadioButton("&Binary")
self.buttonLayout.addWidget(self.radio1)
self.radio1.setChecked(True)
self.radio2 = QRadioButton("Decimal &Fraction")
self.buttonLayout.addWidget(self.radio2)
self.radio3 = QRadioButton("Decimal &Integer")
self.buttonLayout.addWidget(self.radio3)
self.setLayout(self.buttonLayout)
class LogTablex(QTableWidget):
def __init__(self, WordLength:int = 24):
super().__init__()
self.WordLength = WordLength
self.initTable(["Note", "X", "Q", "N", "C", "O"])
def initTable(self, headerlist):
font = QFont()
font.setFamily = "Courier New"
font.setPointSize(8)
self.setFont(font)
self.horizontalHeader().setStyleSheet("QHeaderView::section { background-color:lightgrey; }")
self.setColumnCount(len(headerlist))
self.setHorizontalHeaderLabels(headerlist)
self.setRowCount(0)
self.start_newrow()
self.str = '0' * self.WordLength + ' '
self.setCellWidget(0, 0, QLabel("note"))
self.setCellWidget(0, 1, QLabel(self.str))
self.setCellWidget(0, 2, QLabel(self.str))
self.setCellWidget(0, 3, QLabel(self.str))
self.setCellWidget(0, 4, QLabel("1"))
self.setCellWidget(0, 5, QLabel("1"))
self.verticalHeader().setDefaultSectionSize(22)
self.horizontalHeader().setSectionResizeMode(3)
self.resizeColumnsToContents()
def start_newrow(self, note:str = "new note "):
self.insertRow(self.rowCount())
self.setCellWidget(self.rowCount() - 1, 0, QLabel(note))
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = App()
sys.exit(app.exec_())
此版本生成第一张图片。如果您取消注释显示的两行,它会生成第二个版本。我已经为此苦苦挣扎了一段时间,但我无法理解如何让右手 table 表现出来。我希望有人能阐明它。
我正在使用 PyQt5,最新版本 Python 大约 1 周前下载。我在 运行宁 Windows 10.
这是我第一次 post 来这里。希望格式正确
首先,我建议您在 CMD 或终端中执行脚本,因为很多时候 IDE 会隐藏我们的错误,例如,如果我执行您的代码,我会收到以下消息:
QWidget::setLayout: Attempting to set QLayout "" on App "", which already has a layout
QWidget::setLayout: Attempting to set QLayout "" on App "", which already has a layout
QWidget::setLayout: Attempting to set QLayout "" on App "", which already has a layout
那个错误是因为 QMainWindow 是一个特殊的小部件,具有如下图所示的预设布局:
在您的情况下,您正在尝试替换它,正确的做法是将布局设置为 centralwidget。
问题似乎是您重复添加布局并导致了问题,因此我改进了您的代码以建立位置(我建议不要制作 class 的布局属性,因为它们通常不会被重复使用)
from PyQt5 import QtCore, QtGui, QtWidgets
class App(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
self.title = 'PyQt5 simple window'
self.left, self.top, self.width, self.height = 10, 50, 800, 480
self.initUI()
def initUI(self):
self.setWindowTitle(self.title)
self.setGeometry(self.left, self.top, self.width, self.height)
# Parent layout
self.central_Widget = QtWidgets.QWidget()
self.setCentralWidget(self.central_Widget)
central_Layout = QtWidgets.QHBoxLayout(self.central_Widget)
leftpanel_Layout = QtWidgets.QVBoxLayout()
leftpanel_Layout.addWidget(DataSelectionGroup("Data entry mode"))
leftpanel_Layout.addStretch()
rightpanel_Layout = QtWidgets.QVBoxLayout()
self.myLogTable = LogTablex()
rightpanel_Layout.addWidget(self.myLogTable)
central_Layout.addLayout(leftpanel_Layout)
central_Layout.addLayout(rightpanel_Layout)
self.setWindowTitle("Demo")
self.show()
class DataSelectionGroup(QtWidgets.QGroupBox):
""" Create a group of Radio Buttons to choose type of data entry """
def __init__(self, title):
super().__init__(title)
buttonLayout = QtWidgets.QVBoxLayout(self)
# add radio buttons to choose which mode of data entry to use
self.radio1 = QtWidgets.QRadioButton("&Binary")
buttonLayout.addWidget(self.radio1)
self.radio1.setChecked(True)
self.radio2 = QtWidgets.QRadioButton("Decimal &Fraction")
buttonLayout.addWidget(self.radio2)
self.radio3 = QtWidgets.QRadioButton("Decimal &Integer")
buttonLayout.addWidget(self.radio3)
class LogTablex(QtWidgets.QTableWidget):
def __init__(self, WordLength:int = 24):
super().__init__()
self.WordLength = WordLength
self.initTable(["Note", "X", "Q", "N", "C", "O"])
def initTable(self, headerlist):
font = QtGui.QFont("Courier New", 8)
self.setFont(font)
self.horizontalHeader().setStyleSheet("QHeaderView::section { background-color:lightgrey; }")
self.setColumnCount(len(headerlist))
self.setHorizontalHeaderLabels(headerlist)
self.setRowCount(0)
self.start_newrow()
text = '0' * self.WordLength + ' '
for i, val in enumerate(("note", text, text, text, "1", "1",)):
self.setCellWidget(0, i, QtWidgets.QLabel(val))
self.verticalHeader().setDefaultSectionSize(22)
self.horizontalHeader().setSectionResizeMode(3)
self.resizeColumnsToContents()
def start_newrow(self, note: str = "new note "):
self.insertRow(self.rowCount())
self.setCellWidget(self.rowCount() - 1, 0, QtWidgets.QLabel(note))
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
ex = App()
sys.exit(app.exec_())
更新:
第一个布局占用最小space,另一个布局展开,在添加rightpanel_Layout
的时候,必须添加一段1
,所以改成:
central_Layout.addLayout(leftpanel_Layout)
central_Layout.addLayout(rightpanel_Layout, stretch=1) # <---
也不需要建立固定的锚点,布局会为您完成工作:
class DataEntryGroupLayout(QtWidgets.QGroupBox):
def __init__(self, title):
super().__init__(title)
_form = QtWidgets.QFormLayout(self)
# Add the form controls to the group box = list required
_pairlist = ["x value", "n value"]
for _pair in _pairlist:
_label = QtWidgets.QLabel(_pair)
_value = QtWidgets.QLineEdit()
_form.addRow(_label, _value)
我是一位经验丰富的(如果有点生疏的话)Windows 程序员。我正在尝试创建我在 1963 年设计的计算机 (Ferranti Argus 400) 的部分逻辑模拟(是的,我就是那么老!
不过,我是 Python 编程的新手,在使用 QTableWidget 时遇到格式问题。
我想将其显示在右侧,旁边是一组控件,用于输入模拟功能的测试数据(并使用 QTableWidget 显示模拟将要执行的步骤 运行到)例如逐位显示乘法器的工作。
我正在尝试使用 QHBoxLayout() 作为带有两个嵌入框的外部容器。左侧的 QVBox 将包含我的模拟数据条目,右侧的框将包含 QTablewidget 对象,滚动显示计算机寄存器的状态。
QTableWidget 工作正常(下面的是一种简化),直到我在左侧添加一个包含控件的 Vbox(此处包含一组)。 Table 从其全宽缩小并将其自身定位在剩余 space 的右侧。我希望它位于其他控件的左侧,并在空间不足时滚动(目标机器有 32*24 位寄存器可以显示,尽管我最初将使用 8 位进行测试)
屏幕左侧有一个组
在此处输入图片描述
class App(QMainWindow):
def __init__(self):
super().__init__()
self.title = 'PyQt5 simple window'
self.left = 10
self.top = 50
self.width = 800
self.height = 480
self.initUI()
def initUI(self):
self.setWindowTitle(self.title)
self.setGeometry(self.left, self.top, self.width, self.height)
# Parent layout
self.central_Widget = QWidget(self)
self.setCentralWidget(self.central_Widget)
self.central_Layout = QHBoxLayout()
# Configure left panel as Vbox
self.leftpanel_Layout = QVBoxLayout()
#
self.leftpanel_Layout.addWidget(DataSelectionGroup("Data entry mode"))
#
# Add stretch to bottom of panel
self.leftpanel_Layout.addStretch(0)
self.rightpanel_Layout = QVBoxLayout()
self.myLogTable = LogTablex()
self.rightpanel_Layout.addWidget(self.myLogTable)
self.setLayout(self.rightpanel_Layout)
# Add left panel layout to central layout
# uncomment these lines to see the unwanted behaviour
#self.central_Layout.addLayout(self.leftpanel_Layout)
#self.central_Layout.addStretch(0)
self.setLayout(self.central_Layout)
self.central_Layout.addLayout(self.rightpanel_Layout)
self.setLayout(self.central_Layout)
self.central_Widget.setLayout(self.central_Layout)
self.setWindowTitle("Demo")
self.show()
class DataSelectionGroup(QGroupBox):
""" Create a group of Radio Buttons to choose type of data entry """
def __init__(self, title):
super().__init__(title)
self.buttonLayout = QVBoxLayout()
# add radio buttons to choose which mode of data entry to use
self.radio1 = QRadioButton("&Binary")
self.buttonLayout.addWidget(self.radio1)
self.radio1.setChecked(True)
self.radio2 = QRadioButton("Decimal &Fraction")
self.buttonLayout.addWidget(self.radio2)
self.radio3 = QRadioButton("Decimal &Integer")
self.buttonLayout.addWidget(self.radio3)
self.setLayout(self.buttonLayout)
class LogTablex(QTableWidget):
def __init__(self, WordLength:int = 24):
super().__init__()
self.WordLength = WordLength
self.initTable(["Note", "X", "Q", "N", "C", "O"])
def initTable(self, headerlist):
font = QFont()
font.setFamily = "Courier New"
font.setPointSize(8)
self.setFont(font)
self.horizontalHeader().setStyleSheet("QHeaderView::section { background-color:lightgrey; }")
self.setColumnCount(len(headerlist))
self.setHorizontalHeaderLabels(headerlist)
self.setRowCount(0)
self.start_newrow()
self.str = '0' * self.WordLength + ' '
self.setCellWidget(0, 0, QLabel("note"))
self.setCellWidget(0, 1, QLabel(self.str))
self.setCellWidget(0, 2, QLabel(self.str))
self.setCellWidget(0, 3, QLabel(self.str))
self.setCellWidget(0, 4, QLabel("1"))
self.setCellWidget(0, 5, QLabel("1"))
self.verticalHeader().setDefaultSectionSize(22)
self.horizontalHeader().setSectionResizeMode(3)
self.resizeColumnsToContents()
def start_newrow(self, note:str = "new note "):
self.insertRow(self.rowCount())
self.setCellWidget(self.rowCount() - 1, 0, QLabel(note))
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = App()
sys.exit(app.exec_())
此版本生成第一张图片。如果您取消注释显示的两行,它会生成第二个版本。我已经为此苦苦挣扎了一段时间,但我无法理解如何让右手 table 表现出来。我希望有人能阐明它。
我正在使用 PyQt5,最新版本 Python 大约 1 周前下载。我在 运行宁 Windows 10.
这是我第一次 post 来这里。希望格式正确
首先,我建议您在 CMD 或终端中执行脚本,因为很多时候 IDE 会隐藏我们的错误,例如,如果我执行您的代码,我会收到以下消息:
QWidget::setLayout: Attempting to set QLayout "" on App "", which already has a layout
QWidget::setLayout: Attempting to set QLayout "" on App "", which already has a layout
QWidget::setLayout: Attempting to set QLayout "" on App "", which already has a layout
那个错误是因为 QMainWindow 是一个特殊的小部件,具有如下图所示的预设布局:
在您的情况下,您正在尝试替换它,正确的做法是将布局设置为 centralwidget。
问题似乎是您重复添加布局并导致了问题,因此我改进了您的代码以建立位置(我建议不要制作 class 的布局属性,因为它们通常不会被重复使用)
from PyQt5 import QtCore, QtGui, QtWidgets
class App(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
self.title = 'PyQt5 simple window'
self.left, self.top, self.width, self.height = 10, 50, 800, 480
self.initUI()
def initUI(self):
self.setWindowTitle(self.title)
self.setGeometry(self.left, self.top, self.width, self.height)
# Parent layout
self.central_Widget = QtWidgets.QWidget()
self.setCentralWidget(self.central_Widget)
central_Layout = QtWidgets.QHBoxLayout(self.central_Widget)
leftpanel_Layout = QtWidgets.QVBoxLayout()
leftpanel_Layout.addWidget(DataSelectionGroup("Data entry mode"))
leftpanel_Layout.addStretch()
rightpanel_Layout = QtWidgets.QVBoxLayout()
self.myLogTable = LogTablex()
rightpanel_Layout.addWidget(self.myLogTable)
central_Layout.addLayout(leftpanel_Layout)
central_Layout.addLayout(rightpanel_Layout)
self.setWindowTitle("Demo")
self.show()
class DataSelectionGroup(QtWidgets.QGroupBox):
""" Create a group of Radio Buttons to choose type of data entry """
def __init__(self, title):
super().__init__(title)
buttonLayout = QtWidgets.QVBoxLayout(self)
# add radio buttons to choose which mode of data entry to use
self.radio1 = QtWidgets.QRadioButton("&Binary")
buttonLayout.addWidget(self.radio1)
self.radio1.setChecked(True)
self.radio2 = QtWidgets.QRadioButton("Decimal &Fraction")
buttonLayout.addWidget(self.radio2)
self.radio3 = QtWidgets.QRadioButton("Decimal &Integer")
buttonLayout.addWidget(self.radio3)
class LogTablex(QtWidgets.QTableWidget):
def __init__(self, WordLength:int = 24):
super().__init__()
self.WordLength = WordLength
self.initTable(["Note", "X", "Q", "N", "C", "O"])
def initTable(self, headerlist):
font = QtGui.QFont("Courier New", 8)
self.setFont(font)
self.horizontalHeader().setStyleSheet("QHeaderView::section { background-color:lightgrey; }")
self.setColumnCount(len(headerlist))
self.setHorizontalHeaderLabels(headerlist)
self.setRowCount(0)
self.start_newrow()
text = '0' * self.WordLength + ' '
for i, val in enumerate(("note", text, text, text, "1", "1",)):
self.setCellWidget(0, i, QtWidgets.QLabel(val))
self.verticalHeader().setDefaultSectionSize(22)
self.horizontalHeader().setSectionResizeMode(3)
self.resizeColumnsToContents()
def start_newrow(self, note: str = "new note "):
self.insertRow(self.rowCount())
self.setCellWidget(self.rowCount() - 1, 0, QtWidgets.QLabel(note))
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
ex = App()
sys.exit(app.exec_())
更新:
第一个布局占用最小space,另一个布局展开,在添加rightpanel_Layout
的时候,必须添加一段1
,所以改成:
central_Layout.addLayout(leftpanel_Layout)
central_Layout.addLayout(rightpanel_Layout, stretch=1) # <---
也不需要建立固定的锚点,布局会为您完成工作:
class DataEntryGroupLayout(QtWidgets.QGroupBox):
def __init__(self, title):
super().__init__(title)
_form = QtWidgets.QFormLayout(self)
# Add the form controls to the group box = list required
_pairlist = ["x value", "n value"]
for _pair in _pairlist:
_label = QtWidgets.QLabel(_pair)
_value = QtWidgets.QLineEdit()
_form.addRow(_label, _value)