从列表中的一个 QGraphicsItem 向该列表中的所有项目发出信号
Signaling from one QGraphicsItem in a list to all items in that list
背景:我正在尝试制作一个日历应用程序。我通过为给定 month.All 中的每个日期排列 QGraphicsItemGroup 元素来创建月份的自定义视图 QGraphicsItemGroup 元素位于列表中以便于迭代。当鼠标悬停在日期上时,背景变为灰色。单击日期时,背景变为蓝色。单击另一个日期时,它会标记为蓝色,并且会清除之前的日期。
月份概览
问题:我只希望最后点击的日期有蓝色背景,而不是所有点击的日期。所有其他日期元素都应该有白色背景。我不知道如何将信号从日期列表中的一个 QGraphicsItemGroup 元素发送到该列表中的所有元素。
当前代码:
# coding=utf-8
from PyQt4.QtCore import Qt
import sys
from datetime import *
from calendar import Calendar
from PyQt4.QtGui import (QApplication, QDialog, QGraphicsView, QGraphicsScene, QGraphicsRectItem, QVBoxLayout,
QGraphicsSimpleTextItem, QBrush, QFont, QGraphicsItemGroup)
class GraficsView(QDialog):
def __init__(self, parent=None):
monthnames = ("Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "November",
"Dezember")
super(GraficsView, self).__init__(parent)
self.viewbox = QGraphicsView()
layout = QVBoxLayout()
layout.addWidget(self.viewbox)
self.setLayout(layout)
self.scene = QGraphicsScene(self.viewbox)
self.scene.setSceneRect(0,0,701,501)
self.calendarList = CalendarList(datetime(2018,2,1), self.scene)
self.viewbox.setScene(self.scene)
class DateElement(QGraphicsItemGroup):
def __init__(self, scene, status=False, date=datetime.today(), coordinates=()):
QGraphicsItemGroup.__init__(self, scene=scene)
wochentage = ("Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag", "Sonntag")
self.status = status
if self.status:
self.setdate(date)
self.setcoordinates(coordinates)
def setdate(self, date):
wochentage = ("Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag", "Sonntag")
self.date = date
self.dayname = wochentage[self.date.weekday()]
self.daynumber = self.date.day
def setcoordinates(self, coordinates):
self.coordinates = coordinates
self.rectangle = QGraphicsRectItem(self.coordinates[0], self.coordinates[1], self.coordinates[2],
self.coordinates[3])
self.rectangle.setAcceptHoverEvents(True)
self.fontA = QFont("Verdana", 10, QFont.Bold)
self.fontB = QFont("Verdana", 18, QFont.Bold)
self.lableday = QGraphicsSimpleTextItem()
if self.dayname in ("Samstag", "Sonntag"):
self.lableday.setBrush(QBrush(Qt.red))
else:
self.lableday.setBrush(QBrush(Qt.black))
self.lableday.setFont(self.fontA)
self.lableday.setText(self.dayname)
self.lableday.setPos(self.coordinates[0]+3, self.coordinates[1])
self.lablenumber = QGraphicsSimpleTextItem()
if self.dayname in ("Samstag", "Sonntag"):
self.lablenumber.setBrush(QBrush(Qt.red))
else:
self.lablenumber.setBrush(QBrush(Qt.black))
self.lablenumber.setFont(self.fontB)
self.lablenumber.setText(str(self.daynumber)+".")
self.lablenumber.setPos(self.coordinates[0]+3, self.coordinates[1]+12)
self.addToGroup(self.rectangle)
self.addToGroup(self.lableday)
self.addToGroup(self.lablenumber)
def hoverEnterEvent(self, event):
self.rectangle.setBrush(QBrush(Qt.lightGray))
self.update()
def hoverLeaveEvent(self, event):
self.rectangle.setBrush(QBrush(Qt.white))
self.update()
def mousePressEvent(self, event):
self.rectangle.setAcceptHoverEvents(False)
self.rectangle.setBrush(QBrush(Qt.blue))
self.update()
def clearRectangle(self):
self.rectangle.setAcceptHoverEvents(True)
self.rectangle.setBrush(QBrush(Qt.white))
self.update()
class CalendarList():
def __init__(self, date, scene):
self.date = date
self.scene = scene
self.dateelements = []
self.createdates()
def createdates(self):
weekcount = 0
daycount = 0
calendarobjekt = Calendar()
for dateobjekt in calendarobjekt.itermonthdates(self.date.year, self.date.month):
if daycount < 7:
if dateobjekt.month == self.date.month:
self.dateelements.append(DateElement(self.scene, True, dateobjekt, (daycount*100, weekcount*100, 100, 100)))
else:
self.dateelements.append(DateElement(self.scene))
daycount += 1
else:
daycount = 0
weekcount += 1
if dateobjekt.month == self.date.month:
self.dateelements.append(DateElement(self.scene, True, dateobjekt, (daycount*100, weekcount*100, 100, 100)))
else:
self.dateelements.append(DateElement(self.scene))
daycount += 1
app = QApplication(sys.argv)
form = GraficsView()
form.show()
app.exec_()
可能的解决方案:
- 在 CalendarList class 中创建一个信号,该信号可以由 DateElement 引发,然后触发 CalendarList 中所有项目的 clearBackground 方法。
CalendarList
不是继承自 QObject
的 class,因此它不支持信号,我的回答是通过 scene().items()
获取项目的意义, 那么我们就把DateElement
class 的item过滤出来, 状态为true, 那么就会用到clearRectangle()
方法:
def mousePressEvent(self, event):
for item in self.scene().items():
if isinstance(item, DateElement):
if item.status:
item.clearRectangle()
self.rectangle.setAcceptHoverEvents(False)
self.rectangle.setBrush(QBrush(Qt.blue))
#self.update()
背景:我正在尝试制作一个日历应用程序。我通过为给定 month.All 中的每个日期排列 QGraphicsItemGroup 元素来创建月份的自定义视图 QGraphicsItemGroup 元素位于列表中以便于迭代。当鼠标悬停在日期上时,背景变为灰色。单击日期时,背景变为蓝色。单击另一个日期时,它会标记为蓝色,并且会清除之前的日期。
月份概览
问题:我只希望最后点击的日期有蓝色背景,而不是所有点击的日期。所有其他日期元素都应该有白色背景。我不知道如何将信号从日期列表中的一个 QGraphicsItemGroup 元素发送到该列表中的所有元素。
当前代码:
# coding=utf-8
from PyQt4.QtCore import Qt
import sys
from datetime import *
from calendar import Calendar
from PyQt4.QtGui import (QApplication, QDialog, QGraphicsView, QGraphicsScene, QGraphicsRectItem, QVBoxLayout,
QGraphicsSimpleTextItem, QBrush, QFont, QGraphicsItemGroup)
class GraficsView(QDialog):
def __init__(self, parent=None):
monthnames = ("Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "November",
"Dezember")
super(GraficsView, self).__init__(parent)
self.viewbox = QGraphicsView()
layout = QVBoxLayout()
layout.addWidget(self.viewbox)
self.setLayout(layout)
self.scene = QGraphicsScene(self.viewbox)
self.scene.setSceneRect(0,0,701,501)
self.calendarList = CalendarList(datetime(2018,2,1), self.scene)
self.viewbox.setScene(self.scene)
class DateElement(QGraphicsItemGroup):
def __init__(self, scene, status=False, date=datetime.today(), coordinates=()):
QGraphicsItemGroup.__init__(self, scene=scene)
wochentage = ("Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag", "Sonntag")
self.status = status
if self.status:
self.setdate(date)
self.setcoordinates(coordinates)
def setdate(self, date):
wochentage = ("Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag", "Sonntag")
self.date = date
self.dayname = wochentage[self.date.weekday()]
self.daynumber = self.date.day
def setcoordinates(self, coordinates):
self.coordinates = coordinates
self.rectangle = QGraphicsRectItem(self.coordinates[0], self.coordinates[1], self.coordinates[2],
self.coordinates[3])
self.rectangle.setAcceptHoverEvents(True)
self.fontA = QFont("Verdana", 10, QFont.Bold)
self.fontB = QFont("Verdana", 18, QFont.Bold)
self.lableday = QGraphicsSimpleTextItem()
if self.dayname in ("Samstag", "Sonntag"):
self.lableday.setBrush(QBrush(Qt.red))
else:
self.lableday.setBrush(QBrush(Qt.black))
self.lableday.setFont(self.fontA)
self.lableday.setText(self.dayname)
self.lableday.setPos(self.coordinates[0]+3, self.coordinates[1])
self.lablenumber = QGraphicsSimpleTextItem()
if self.dayname in ("Samstag", "Sonntag"):
self.lablenumber.setBrush(QBrush(Qt.red))
else:
self.lablenumber.setBrush(QBrush(Qt.black))
self.lablenumber.setFont(self.fontB)
self.lablenumber.setText(str(self.daynumber)+".")
self.lablenumber.setPos(self.coordinates[0]+3, self.coordinates[1]+12)
self.addToGroup(self.rectangle)
self.addToGroup(self.lableday)
self.addToGroup(self.lablenumber)
def hoverEnterEvent(self, event):
self.rectangle.setBrush(QBrush(Qt.lightGray))
self.update()
def hoverLeaveEvent(self, event):
self.rectangle.setBrush(QBrush(Qt.white))
self.update()
def mousePressEvent(self, event):
self.rectangle.setAcceptHoverEvents(False)
self.rectangle.setBrush(QBrush(Qt.blue))
self.update()
def clearRectangle(self):
self.rectangle.setAcceptHoverEvents(True)
self.rectangle.setBrush(QBrush(Qt.white))
self.update()
class CalendarList():
def __init__(self, date, scene):
self.date = date
self.scene = scene
self.dateelements = []
self.createdates()
def createdates(self):
weekcount = 0
daycount = 0
calendarobjekt = Calendar()
for dateobjekt in calendarobjekt.itermonthdates(self.date.year, self.date.month):
if daycount < 7:
if dateobjekt.month == self.date.month:
self.dateelements.append(DateElement(self.scene, True, dateobjekt, (daycount*100, weekcount*100, 100, 100)))
else:
self.dateelements.append(DateElement(self.scene))
daycount += 1
else:
daycount = 0
weekcount += 1
if dateobjekt.month == self.date.month:
self.dateelements.append(DateElement(self.scene, True, dateobjekt, (daycount*100, weekcount*100, 100, 100)))
else:
self.dateelements.append(DateElement(self.scene))
daycount += 1
app = QApplication(sys.argv)
form = GraficsView()
form.show()
app.exec_()
可能的解决方案:
- 在 CalendarList class 中创建一个信号,该信号可以由 DateElement 引发,然后触发 CalendarList 中所有项目的 clearBackground 方法。
CalendarList
不是继承自 QObject
的 class,因此它不支持信号,我的回答是通过 scene().items()
获取项目的意义, 那么我们就把DateElement
class 的item过滤出来, 状态为true, 那么就会用到clearRectangle()
方法:
def mousePressEvent(self, event):
for item in self.scene().items():
if isinstance(item, DateElement):
if item.status:
item.clearRectangle()
self.rectangle.setAcceptHoverEvents(False)
self.rectangle.setBrush(QBrush(Qt.blue))
#self.update()