作为python的首发,试图在遇到问题时从聪明人那里获得帮助。那就是现在:
我要将一个列表中的项目(Qt场景项目)相互比较,并制作相互冲突的单独项目组。
请帮我处理代码:
class MainWin(QMainWindow):
def __init__(self):
super(MainWin, self).__init__()
self.Win()
self.L = self.buildAllWalls()
items = self.scene.items()
allGroups = groupItemsFromList(None, items)
self.paintGroups(allGroups)
print len(allGroups)
def paintGroups(self, groups):
for g in groups :
color = QColor(0, 0, 0)
# RANDOM COLOR
namcol = "#%s" % "".join([hex(randrange(0, 255))[2:] for i in range(3)])
color.setNamedColor(namcol)
while color.isValid() == False : # ERROR CHECK
namcol = "#%s" % "".join([hex(randrange(0, 255))[2:] for i in range(3)])
color.setNamedColor(namcol)
pen = QPen(color, 14, Qt.SolidLine)
for w in g :
w.setPen(pen)
def Win(self):
self.scene = QGraphicsScene()
self.sView = QGraphicsView(self.scene)
self.sView.setRenderHint(QPainter.Antialiasing)
self.sView.setAlignment( Qt.AlignLeft | Qt.AlignTop )
self.setCentralWidget(self.sView)
self.setGeometry(20, 380, 400, 300)
self.show()
def buildAllWalls(self):
data = self.wallCoordinates()
for p in range(len(data)) :
ptA = QPointF(data[p][0], data[p][1])
ptB = QPointF(data[p][2], data[p][3])
self.wall(ptA, ptB)
def wall(self, ptA, ptB):
pen = QPen(QColor(100, 100, 100), 14, Qt.SolidLine)
currL = self.scene.addLine(QLineF(ptA.x(), ptA.y(), ptB.x(), ptB.y()))
currL.setPen(pen)
return currL
#[50,75,325,75],
def wallCoordinates(self):
data = [[50,100,150,100],[175,200,125,200],[175,275,125,275],[175,275,175,200],
[150,150,150,100],[175,100,225,100],[250,100,325,100],[350,125,175,125],
[50,125,125,125],[125,175,125,125],[150,150,175,150],[175,150,175,200],
[50,150,100,150],[100,150,100,200],[100,200,125,200],[50,175,75,175],
[75,225,75,175],[75,225,125,225],[125,275,125,225]]
return data
def main():
app = QApplication(sys.argv)
ex = MainWin()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
答案 0 :(得分:1)
以下是我写这个的方法:
def groupItemsFromList(self, itemList):
tmp = itemList[:]
allGroups = []
while tmp:
it = tmp.pop(0)
currentGroup = [it]
# loop from back to front so we can remove items safely
for i in range(len(tmp)-1, -1, -1):
if it.collidesWithItem(tmp[i]):
currentGroup.append(tmp.pop(i))
allGroups.append(currentGroup)
return allGroups
例如:
class Test(object):
def __init__(self, key):
self.key = key
def collidesWithItem(self, other):
return isinstance(other, self.__class__) and self.key == other.key
def __repr__(self):
return '{0}({1})'.format(self.__class__.__name__, self.key)
example = [Test(1), Test(2), Test(1), Test(1), Test(3), Test(2), Test(3), Test(4)]
print groupItemsFromList(None, example)
输出:
[[Test(1), Test(1), Test(1)], [Test(2), Test(2)], [Test(3), Test(3)], [Test(4)]]
这假设所有与物品碰撞的物品也会相互碰撞。
编辑:听起来假设无效,请尝试以下(未经测试):
def groupItemsFromList(self, itemList):
tmp = itemList[:]
allGroups = []
while tmp:
it = tmp.pop(0)
currentGroup = [it]
i = len(tmp) - 1
while i >= 0:
if any(x.collidesWithItem(tmp[i]) for x in currentGroup):
currentGroup.append(tmp.pop(i))
i = len(tmp) - 1
else:
i -= 1
allGroups.append(currentGroup)
return allGroups
答案 1 :(得分:1)
看起来你可以这样做:
def groupItemsFromList(self, itemList):
"""
Make a list of lists, where each list is composed of the
items (excepting itself, of course) that an item collides with.
"""
return [
[item for item in itemList[:i] + itemList[i:] if item.collidesWithItem(x)]
for i, x in enumerate(itemList)
]
击> <击> 撞击>
itemList[:i] + itemList[i:]
是“我希望除了第i个项目之外的原始列表的所有元素。”的python习语。
def groupItemsFromList(self, itemList):
def collision_indexes(i, target):
return [i] + [j for j, item in enumerate(itemList[i + 1:], start=i + 1) if item.collidesWithItem(target)]
processed = set()
results = []
for i, target in enumerate(itemList):
if i not in processed:
indexes = collision_indexes(i, target)
processed.update(indexes)
results.append([itemList[j] for j in indexes])
return results
这里唯一的优点是这是无副作用的代码。原始数据没有变异,只有应用于数据的函数和对新的临时数据结构所做的更改。