我是一位经验丰富的(即使很生锈)Windows程序员。我正在尝试创建我在1963年设计的计算机(Ferranti Argus 400)的部分逻辑仿真(是的,我那年老!
但是我是Python编程的新手,并且在使用QTableWidget时遇到格式化问题。
我想在一组控件旁边显示该控件,以便为模拟功能输入测试数据(并使用QTableWidget显示模拟将要执行的步骤),例如,显示乘法器位的工作情况一点点。
我试图将QHBoxLayout()用作具有两个嵌入式Box的外部容器。左边的QVBox将包含用于仿真的数据条目,右边的框将包含一个QTablewidget对象,该对象具有计算机寄存器状态的滚动显示。
QTableWidget正常工作(下面的一个是简化的),直到我在左侧添加一个包含控件的Vbox(此处包含一组)为止。表格从其整个宽度开始缩小,并将其自身定位在剩余空间的右侧。我希望它在其他控件旁边的左侧,并在没有足够空间的情况下滚动它(目标机器有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_())
此版本产生第一张图像。如果取消注释显示的两行,则会生成第二个版本。我已经为此进行了一段时间的斗争,我无法理解如何使右手桌子发挥作用。我希望有人能对此有所启发。
我正在将PyQt5与1周前下载的最新版本的Python配合使用。我正在Windows 10上运行。
这是我在这里的第一篇文章。我希望它的格式正确
答案 0 :(得分:0)
首先,我建议您在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是具有预设布局的特殊小部件,如下图所示:
在您要更换的情况下,正确的做法是将布局设置为中央窗口。
要解决此问题,似乎是反复添加布局,这会导致问题,因此,我改进了代码以建立位置(我建议不要设置类的layout属性,因为通常不会重复使用它们)
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_())
更新:
要使第一个布局占用最小空间,而另一个布局要扩展,则在添加1
时必须添加一段rightpanel_Layout
,因此将其更改为:
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)