<p>绘制小部件时,将使用内部坐标,但<a href="http://doc.qt.io/qt-5/qwidget.html#geometry-prop" rel="nofollow noreferrer">^{<cd1>}</a>是相对于父级的坐标,因此不应使用它,而应使用<a href="http://doc.qt.io/qt-5/qwidget.html#rect-prop" rel="nofollow noreferrer">^{<cd2>}</a>。你知道吗</p>
<pre><code>from PyQt5 import QtCore, QtGui, QtWidgets
class Simulator(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
self.stdout = QtWidgets.QTextEdit()
self.stderr = QtWidgets.QTextEdit()
self.exec = QtWidgets.QTextEdit()
self.frame = QtWidgets.QFrame()
self.setCentralWidget(self.frame)
self.grid = QtWidgets.QGridLayout(self.frame)
self.map = SimulatedFieldMap()
# setting splitters
splitter_r = QtWidgets.QSplitter(QtCore.Qt.Vertical)
splitter_l = QtWidgets.QSplitter(QtCore.Qt.Vertical)
splitter_h = QtWidgets.QSplitter(QtCore.Qt.Horizontal)
splitter_h.addWidget(splitter_l)
splitter_h.addWidget(splitter_r)
#
# top left
frame = QtWidgets.QFrame()
box = QtWidgets.QVBoxLayout(frame)
splitter_l.addWidget(frame)
label = QtWidgets.QLabel('Map')
box.addWidget(label)
box.addWidget(self.map)
#
# bottom left
frame = QtWidgets.QFrame()
box = QtWidgets.QVBoxLayout(frame)
box.addWidget(QtWidgets.QLabel('Exec'))
box.addWidget(self.exec)
splitter_l.addWidget(frame)
# -
# top right
frame = QtWidgets.QFrame()
box = QtWidgets.QVBoxLayout(frame)
splitter_r.addWidget(frame)
box.addWidget(QtWidgets.QLabel('STDOUT'))
box.addWidget(self.stdout)
# -
# bottom right
frame = QtWidgets.QFrame()
box = QtWidgets.QVBoxLayout(frame)
splitter_r.addWidget(frame)
box.addWidget(QtWidgets.QLabel('STDERR'))
box.addWidget(self.stderr)
# -
screen = QtWidgets.QDesktopWidget().screenGeometry()
self.grid.addWidget(splitter_h, 0, 0)
splitter_h.setSizes((screen.width() * 0.7, screen.width() * 0.3))
splitter_l.setSizes((screen.height() * 0.7, screen.height() * 0.3))
splitter_r.setSizes((screen.height() * 0.7, screen.height() * 0.3))
class SimulatedFieldMap(QtWidgets.QWidget):
def __init__(self):
super().__init__()
def paintEvent(self, event):
qp = QtGui.QPainter(self)
self.paintMap(qp)
def paintMap(self, qp):
qp.setBrush(QtGui.QColor(200, 162, 200)) # lilac
qp.setPen(QtGui.QColor(200, 162, 200))
qp.drawRect(self.rect())
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
app.setStyle('Fusion')
sim = Simulator()
sim.showMaximized()
sys.exit(app.exec_())
</code></pre>
<hr/>
<p><strong>更新:</strong>如果要将其放置在特定位置,则不应将其放置在布局中,但标签必须是地图的子项,并使用<code>move()</code>来确定相对于地图左上角的位置。你知道吗</p>
<pre><code># top left
frame = QtWidgets.QFrame()
box = QtWidgets.QVBoxLayout(frame)
box.addWidget(self.map)
splitter_l.addWidget(frame)
label = QtWidgets.QLabel('Map', self.map)
label.move(0, 100)
#
</code></pre>
<p><a href="https://i.stack.imgur.com/z772u.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/z772u.png" alt="enter image description here"/></a></p>
<p><strong>更新:</strong>问题是由于QLabel的垂直大小策略<code>QSizePolicy::Preferred</code>使其扩展,一个简单的解决方案是将其更改为<code>QSizePolicy::Maximum</code>,因此根据字体计算正确的高度。你知道吗</p>
<pre><code># top left
frame = QtWidgets.QFrame()
box = QtWidgets.QVBoxLayout(frame)
splitter_l.addWidget(frame)
label = QtWidgets.QLabel('Map')
sp = label.sizePolicy()
sp.setVerticalPolicy(QtWidgets.QSizePolicy.Maximum)
label.setSizePolicy(sp)
box.addWidget(label)
box.addWidget(self.map)
#
</code></pre>
<p><a href="https://i.stack.imgur.com/Gak1Q.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/Gak1Q.png" alt="enter image description here"/></a></p>