- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我目前在理解 QGraphicsAnchorLayout 在 QGraphicsScene 中的行为时遇到问题。我创建了 4 个框并锚定了每个框的角,但似乎没有正确应用 anchor ,或者至少没有像我认为的那样应用正确。
黄色框应该始终位于 QGraphicsScene 的左上角,即使 GraphicsView 展开时也是如此。蓝色框被锚定为与右侧的黄色框相邻,其顶部与 QGraphicsScene/视口(viewport)的顶部重合。
绿色框的左上角锚定到蓝色框的右下角,同样红色框锚定到绿色框。但这就是我得到的:
我希望黄色框始终位于图形场景/视口(viewport)的顶部。我希望即使向右滚动它也始终保持可见,但我相信这可能是一个单独的问题。但是,当我垂直扩展窗口时,所有框都居中,包括我希望保留在顶部的黄色框。
蓝色、绿色和红色框似乎与我应用的 anchor 没有相似之处。
以下是我用来生成此代码的代码。这些 anchor 如何工作以及我可以采取什么措施来纠正这个问题?
import numpy as np
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import Qt
from debug_utils import *
from PyQt5.QtWidgets import QGraphicsAnchorLayout, QGraphicsWidget, QGraphicsLayoutItem
def qp(p):
return "({}, {})".format(p.x(), p.y())
class box(QtWidgets.QGraphicsWidget):
pressed = QtCore.pyqtSignal()
def __init__(self, rect, color, parent=None):
super(box, self).__init__(parent)
self.raw_rect = rect
self.rect = QtCore.QRectF(rect[0], rect[1], rect[2], rect[3])
self.color = color
def boundingRect(self):
pen_adj = 0
return self.rect.normalized().adjusted(-pen_adj, -pen_adj, pen_adj, pen_adj)
def paint(self, painter, option, widget):
r = self.boundingRect()
brush = QtGui.QBrush()
brush.setColor(QtGui.QColor(self.color))
brush.setStyle(Qt.SolidPattern)
#rect = QtCore.QRect(0, 0, painter.device().width(), painter.device().height())
painter.fillRect(self.boundingRect(), brush)
painter.setRenderHint(QtGui.QPainter.Antialiasing)
painter.setPen(Qt.darkGray)
painter.drawRect(self.boundingRect())
#painter.drawRect(0, 0, max_time*char_spacing, self.bar_height)
def mousePressEvent(self, ev):
self.pressed.emit()
self.update()
def mouseReleaseEvent(self, ev):
self.update()
class GraphicsView(QtWidgets.QGraphicsView):
def __init__(self, parent=None):
super(GraphicsView, self).__init__(parent)
scene = QtWidgets.QGraphicsScene(self)
self.setScene(scene)
self.numbers = []
self.setMouseTracking(True)
l = QGraphicsAnchorLayout()
l.setSpacing(0)
w = QGraphicsWidget()
#painter = QtGui.QPainter(self)
w.setPos(0, 0)
w.setLayout(l)
scene.addItem(w)
self.main_widget = w
self.main_layout = l
self.makeBoxs()
def makeBoxs(self):
rect = [0, 0, 600, 250]
blue_box = box(rect, QtGui.QColor(0, 0, 255, 128))
green_box = box(rect, QtGui.QColor(0, 255, 0, 128))
red_box = box([0, 0, 200, 50], QtGui.QColor(255, 0, 0, 128))
yellow_box_left = box([0, 0, 75, 600], QtGui.QColor(255, 255, 0, 128))
#self.scene().setSceneRect(blue_box.rect)
#self.scene().setSceneRect(bar_green.rect)
# Adding anchors adds the item to the layout which is part of the scene
self.main_layout.addCornerAnchors(yellow_box_left, Qt.TopLeftCorner, self.main_layout, Qt.TopLeftCorner)
self.main_layout.addCornerAnchors(blue_box, Qt.TopLeftCorner, yellow_box_left, Qt.TopRightCorner)
self.main_layout.addCornerAnchors(green_box, Qt.TopLeftCorner, blue_box, Qt.BottomRightCorner)
self.main_layout.addCornerAnchors(red_box, Qt.TopLeftCorner, green_box, Qt.BottomRightCorner)
#self.main_layout.addAnchor(bar_green, Qt.AnchorTop, blue_box, Qt.AnchorBottom)
#self.main_layout.addAnchor(bar_green, Qt.AnchorLeft, blue_box, Qt.AnchorRight)
def printStatus(self, pos):
msg = "Viewport Position: " + str(qp(pos))
v = self.mapToScene(pos)
v = QtCore.QPoint(v.x(), v.y())
msg = msg + ", Mapped to Scene: " + str(qp(v))
v = self.mapToScene(self.viewport().rect()).boundingRect()
msg = msg + ", viewport Mapped to Scene: " + str(qp(v))
v2 = self.mapToScene(QtCore.QPoint(0, 0))
msg = msg + ", (0, 0) to scene: " + qp(v2)
self.parent().statusBar().showMessage(msg)
def mouseMoveEvent(self, event):
pos = event.pos()
self.printStatus(pos)
super(GraphicsView, self).mouseMoveEvent(event)
def resizeEvent(self, event):
self.printStatus(QtGui.QCursor().pos())
h = self.mapToScene(self.viewport().rect()).boundingRect().height()
r = self.sceneRect()
r.setHeight(h)
height = self.viewport().height()
for item in self.items():
item_height = item.boundingRect().height()
super(GraphicsView, self).resizeEvent(event)
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
gv = GraphicsView()
self.setCentralWidget(gv)
self.setGeometry(475, 250, 600, 480)
scene = self.scene = gv.scene()
sb = self.statusBar()
def main():
import sys
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec_())
if __name__ == "__main__":
main()
编辑:添加预期输出根据 anchor 的定义方式,我希望输出如下所示。由于我还无法实际创建我需要的内容,因此我在 PowerPoint 中创建了它。但是,当然,除了让它发挥作用之外,我还希望了解如何在更一般的意义上使用 anchor 。
编辑2:再次感谢您的更新。这并不完全符合我的预期,当我滚动时会出现奇怪的现象。只是为了澄清,
最佳答案
您有 2 个错误:
您的 Box 类构建得很差,它只设置大小,而不是覆盖boundingRect,因为位置将由布局处理。
布局的位置始终相对于它所在的小部件。在您的情况下,您希望 main_layout 的左上角与视口(viewport)的左上角匹配,因此您必须修改 main_widget 的左上角以匹配。
考虑到上述情况,解决方案是:
from PyQt5 import QtCore, QtGui, QtWidgets
def qp(p):
return "({}, {})".format(p.x(), p.y())
class Box(QtWidgets.QGraphicsWidget):
pressed = QtCore.pyqtSignal()
def __init__(self, size, color, parent=None):
super(Box, self).__init__(parent)
self.setMinimumSize(size)
self.setMaximumSize(size)
self.color = color
def paint(self, painter, option, widget):
brush = QtGui.QBrush()
brush.setColor(QtGui.QColor(self.color))
brush.setStyle(QtCore.Qt.SolidPattern)
painter.fillRect(self.boundingRect(), brush)
painter.setRenderHint(QtGui.QPainter.Antialiasing)
painter.setPen(QtCore.Qt.darkGray)
painter.drawRect(self.boundingRect())
def mousePressEvent(self, event):
self.pressed.emit()
super().mousePressEvent(event)
class GraphicsView(QtWidgets.QGraphicsView):
messageChanged = QtCore.pyqtSignal(str)
def __init__(self, parent=None):
super(GraphicsView, self).__init__(parent)
self.setMouseTracking(True)
self.setAlignment(QtCore.Qt.AlignTop | QtCore.Qt.AlignLeft)
scene = QtWidgets.QGraphicsScene(self)
self.setScene(scene)
l = QtWidgets.QGraphicsAnchorLayout()
l.setSpacing(0)
w = QtWidgets.QGraphicsWidget()
self.scene().sceneRectChanged.connect(self.update_widget)
self.horizontalScrollBar().valueChanged.connect(self.update_widget)
self.verticalScrollBar().valueChanged.connect(self.update_widget)
w.setLayout(l)
scene.addItem(w)
self.main_widget = w
self.main_layout = l
self.makeBoxs()
def makeBoxs(self):
blue_box = Box(QtCore.QSizeF(300, 125), QtGui.QColor(0, 0, 255, 128))
green_box = Box(QtCore.QSizeF(300, 125), QtGui.QColor(0, 255, 0, 128))
red_box = Box(QtCore.QSizeF(100, 25), QtGui.QColor(255, 0, 0, 128))
yellow_box = Box(QtCore.QSizeF(37.5, 300), QtGui.QColor(255, 255, 0, 128))
# yellow_box_left top-left
self.main_layout.addCornerAnchors(
yellow_box,
QtCore.Qt.TopLeftCorner,
self.main_layout,
QtCore.Qt.TopLeftCorner,
)
self.main_layout.addCornerAnchors(
blue_box, QtCore.Qt.TopLeftCorner, yellow_box, QtCore.Qt.TopRightCorner
)
self.main_layout.addCornerAnchors(
green_box, QtCore.Qt.TopLeftCorner, blue_box, QtCore.Qt.BottomRightCorner
)
self.main_layout.addCornerAnchors(
red_box, QtCore.Qt.TopLeftCorner, green_box, QtCore.Qt.BottomRightCorner
)
# self.setSceneRect(self.scene().itemsBoundingRect())
def update_widget(self):
vp = self.viewport().mapFromParent(QtCore.QPoint())
tl = self.mapToScene(vp)
geo = self.main_widget.geometry()
geo.setTopLeft(tl)
self.main_widget.setGeometry(geo)
def resizeEvent(self, event):
self.update_widget()
super().resizeEvent(event)
def mouseMoveEvent(self, event):
pos = event.pos()
self.printStatus(pos)
super(GraphicsView, self).mouseMoveEvent(event)
def printStatus(self, pos):
msg = "Viewport Position: " + str(qp(pos))
v = self.mapToScene(pos)
v = QtCore.QPoint(v.x(), v.y())
msg = msg + ", Mapped to Scene: " + str(qp(v))
v = self.mapToScene(self.viewport().rect()).boundingRect()
msg = msg + ", viewport Mapped to Scene: " + str(qp(v))
v2 = self.mapToScene(QtCore.QPoint(0, 0))
msg = msg + ", (0, 0) to scene: " + qp(v2)
self.messageChanged.emit(msg)
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
gv = GraphicsView()
self.setCentralWidget(gv)
self.setGeometry(475, 250, 600, 480)
gv.messageChanged.connect(self.statusBar().showMessage)
def main():
import sys
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec_())
if __name__ == "__main__":
main()
关于python - QGraphicsAnchorLayout 未锚定在 QGraphicsScene 中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58241248/
我正在处理一组标记为 160 个组的 173k 点。我想通过合并最接近的(到 9 或 10 个组)来减少组/集群的数量。我搜索过 sklearn 或类似的库,但没有成功。 我猜它只是通过 knn 聚类
我有一个扁平数字列表,这些数字逻辑上以 3 为一组,其中每个三元组是 (number, __ignored, flag[0 or 1]),例如: [7,56,1, 8,0,0, 2,0,0, 6,1,
我正在使用 pipenv 来管理我的包。我想编写一个 python 脚本来调用另一个使用不同虚拟环境(VE)的 python 脚本。 如何运行使用 VE1 的 python 脚本 1 并调用另一个 p
假设我有一个文件 script.py 位于 path = "foo/bar/script.py"。我正在寻找一种在 Python 中通过函数 execute_script() 从我的主要 Python
这听起来像是谜语或笑话,但实际上我还没有找到这个问题的答案。 问题到底是什么? 我想运行 2 个脚本。在第一个脚本中,我调用另一个脚本,但我希望它们继续并行,而不是在两个单独的线程中。主要是我不希望第
我有一个带有 python 2.5.5 的软件。我想发送一个命令,该命令将在 python 2.7.5 中启动一个脚本,然后继续执行该脚本。 我试过用 #!python2.7.5 和http://re
我在 python 命令行(使用 python 2.7)中,并尝试运行 Python 脚本。我的操作系统是 Windows 7。我已将我的目录设置为包含我所有脚本的文件夹,使用: os.chdir("
剧透:部分解决(见最后)。 以下是使用 Python 嵌入的代码示例: #include int main(int argc, char** argv) { Py_SetPythonHome
假设我有以下列表,对应于及时的股票价格: prices = [1, 3, 7, 10, 9, 8, 5, 3, 6, 8, 12, 9, 6, 10, 13, 8, 4, 11] 我想确定以下总体上最
所以我试图在选择某个单选按钮时更改此框架的背景。 我的框架位于一个类中,并且单选按钮的功能位于该类之外。 (这样我就可以在所有其他框架上调用它们。) 问题是每当我选择单选按钮时都会出现以下错误: co
我正在尝试将字符串与 python 中的正则表达式进行比较,如下所示, #!/usr/bin/env python3 import re str1 = "Expecting property name
考虑以下原型(prototype) Boost.Python 模块,该模块从单独的 C++ 头文件中引入类“D”。 /* file: a/b.cpp */ BOOST_PYTHON_MODULE(c)
如何编写一个程序来“识别函数调用的行号?” python 检查模块提供了定位行号的选项,但是, def di(): return inspect.currentframe().f_back.f_l
我已经使用 macports 安装了 Python 2.7,并且由于我的 $PATH 变量,这就是我输入 $ python 时得到的变量。然而,virtualenv 默认使用 Python 2.6,除
我只想问如何加快 python 上的 re.search 速度。 我有一个很长的字符串行,长度为 176861(即带有一些符号的字母数字字符),我使用此函数测试了该行以进行研究: def getExe
list1= [u'%app%%General%%Council%', u'%people%', u'%people%%Regional%%Council%%Mandate%', u'%ppp%%Ge
这个问题在这里已经有了答案: Is it Pythonic to use list comprehensions for just side effects? (7 个答案) 关闭 4 个月前。 告
我想用 Python 将两个列表组合成一个列表,方法如下: a = [1,1,1,2,2,2,3,3,3,3] b= ["Sun", "is", "bright", "June","and" ,"Ju
我正在运行带有最新 Boost 发行版 (1.55.0) 的 Mac OS X 10.8.4 (Darwin 12.4.0)。我正在按照说明 here构建包含在我的发行版中的教程 Boost-Pyth
学习 Python,我正在尝试制作一个没有任何第 3 方库的网络抓取工具,这样过程对我来说并没有简化,而且我知道我在做什么。我浏览了一些在线资源,但所有这些都让我对某些事情感到困惑。 html 看起来
我是一名优秀的程序员,十分优秀!