在 PyQt 中将信号连接到 类 之间的槽
Connecting signal to slot between classes in PyQt
目的是将顶部classTicTacToe
的信号与QMainWindowclass连接起来。
它抛出一个错误:TicTacToe cannot be converted to PyQt5.QtCore.QObject in this context
#!/usr/bin/env python
from PyQt5.QtCore import (QLineF, QPointF, QRectF, pyqtSignal)
from PyQt5.QtGui import (QIcon, QBrush, QColor, QPainter, QPixmap)
from PyQt5.QtWidgets import (QAction, QMainWindow, QApplication, QGraphicsView, QGraphicsScene, QGraphicsItem,
QGridLayout, QVBoxLayout, QHBoxLayout,
QLabel, QLineEdit, QPushButton)
class TicTacToe(QGraphicsItem):
def __init__(self):
super(TicTacToe, self).__init__()
def paintEvent(self, painter, option, widget):
painter.setPen(Qt.black)
painter.drawLine(0,100,300,100)
def boundingRect(self):
return QRectF(0,0,300,300)
def mousePressEvent(self, event):
pos = event.pos()
self.select(int(pos.x()/100), int(pos.y()/100))
self.update()
super(TicTacToe, self).mousePressEvent(event)
messageSignal = pyqtSignal(int)
class MyGraphicsView(QGraphicsView):
def __init__(self):
super(MyGraphicsView, self).__init__()
scene = QGraphicsScene(self)
self.tic_tac_toe = TicTacToe()
scene.addItem(self.tic_tac_toe)
scene.addPixmap(QPixmap("exit.png"))
self.setScene(scene)
def keyPressEvent(self, event):
key = event.key()
if key == Qt.Key_R:
self.tic_tac_toe.reset()
super(MyGraphicsView, self).keyPressEvent(event)
class Example(QMainWindow):
def __init__(self):
super(Example, self).__init__()
self.y = MyGraphicsView()
self.setCentralWidget(self.y)
self.y.tic_tac_toe.messageSignal.connect (self.messageSlot)
self.initUI()
def messageSlot(self, val):
self.statusBar().showMessage(val)
def initUI(self):
self.toolbar = self.addToolBar('Tools')
self.setGeometry(30, 30, 30, 20)
self.setWindowTitle('Menubar')
self.show()
if __name__ == '__main__':
import sys
app = QApplication(sys.argv)
mainWindow = Example()
mainWindow.showFullScreen()
sys.exit(app.exec_())
问题是您的 class TicTacToe
没有直接或以其他方式从 QObject
继承,这意味着 Qt
无法使用它作为信号源。
尝试从 QGraphicsObject
继承...
class TicTacToe(QGraphicsObject):
def __init__(self):
super(TicTacToe, self).__init__()
只有从 QObject
继承的 class 才具有创建信号的能力,例如 QWidget
、QMainWIndow
、QGraphicsView
继承自 QObject
所以他们可以有信号。但是 QGraphicsItem
没有继承自 QObject
因为效率问题所以他们没有创建信号的能力。如果您想要 QObject
的项目,则必须使用 QGraphicsObject
。此外,项目有 paint()
方法,而不是 paintEvent()
.
class TicTacToe(QGraphicsObject):
def paint(self, painter, option, widget):
painter.setPen(Qt.black)
painter.drawLine(0,100,300,100)
def boundingRect(self):
return QRectF(0,0,300,300)
def mousePressEvent(self, event):
pos = event.pos()
# self.select(int(pos.x()/100), int(pos.y()/100))
self.update()
super(TicTacToe, self).mousePressEvent(event)
messageSignal = pyqtSignal(int)
如果您仍然想使用 QGraphicsItem
,一个可能的解决方法是创建一个 class 来负责通信并继承自 QObject
:
class Helper(QObject):
messageSignal = pyqtSignal(int)
class TicTacToe(QGraphicsObject):
def __init__(self, helper):
super(TicTacToe, self).__init__()
self.helper = helper
def paint(self, painter, option, widget):
painter.setPen(Qt.black)
painter.drawLine(0,100,300,100)
def boundingRect(self):
return QRectF(0,0,300,300)
def mousePressEvent(self, event):
pos = event.pos()
self.helper.emit(10)
# self.select(int(pos.x()/100), int(pos.y()/100))
self.update()
super(TicTacToe, self).mousePressEvent(event)
class MyGraphicsView(QGraphicsView):
def __init__(self):
super(MyGraphicsView, self).__init__()
scene = QGraphicsScene(self)
self.helper = Helper(self)
self.tic_tac_toe = TicTacToe(self.helper)
scene.addItem(self.tic_tac_toe)
scene.addPixmap(QPixmap("exit.png"))
self.setScene(scene)
def keyPressEvent(self, event):
key = event.key()
if key == Qt.Key_R:
self.tic_tac_toe.reset()
super(MyGraphicsView, self).keyPressEvent(event)
class Example(QMainWindow):
def __init__(self):
super(Example, self).__init__()
self.y = MyGraphicsView()
self.setCentralWidget(self.y)
self.helper.messageSignal.connect(self.messageSlot)
self.initUI()
def messageSlot(self, val):
self.statusBar().showMessage(val)
def initUI(self):
self.toolbar = self.addToolBar('Tools')
self.setGeometry(30, 30, 30, 20)
self.setWindowTitle('Menubar')
self.show()
目的是将顶部classTicTacToe
的信号与QMainWindowclass连接起来。
它抛出一个错误:TicTacToe cannot be converted to PyQt5.QtCore.QObject in this context
#!/usr/bin/env python
from PyQt5.QtCore import (QLineF, QPointF, QRectF, pyqtSignal)
from PyQt5.QtGui import (QIcon, QBrush, QColor, QPainter, QPixmap)
from PyQt5.QtWidgets import (QAction, QMainWindow, QApplication, QGraphicsView, QGraphicsScene, QGraphicsItem,
QGridLayout, QVBoxLayout, QHBoxLayout,
QLabel, QLineEdit, QPushButton)
class TicTacToe(QGraphicsItem):
def __init__(self):
super(TicTacToe, self).__init__()
def paintEvent(self, painter, option, widget):
painter.setPen(Qt.black)
painter.drawLine(0,100,300,100)
def boundingRect(self):
return QRectF(0,0,300,300)
def mousePressEvent(self, event):
pos = event.pos()
self.select(int(pos.x()/100), int(pos.y()/100))
self.update()
super(TicTacToe, self).mousePressEvent(event)
messageSignal = pyqtSignal(int)
class MyGraphicsView(QGraphicsView):
def __init__(self):
super(MyGraphicsView, self).__init__()
scene = QGraphicsScene(self)
self.tic_tac_toe = TicTacToe()
scene.addItem(self.tic_tac_toe)
scene.addPixmap(QPixmap("exit.png"))
self.setScene(scene)
def keyPressEvent(self, event):
key = event.key()
if key == Qt.Key_R:
self.tic_tac_toe.reset()
super(MyGraphicsView, self).keyPressEvent(event)
class Example(QMainWindow):
def __init__(self):
super(Example, self).__init__()
self.y = MyGraphicsView()
self.setCentralWidget(self.y)
self.y.tic_tac_toe.messageSignal.connect (self.messageSlot)
self.initUI()
def messageSlot(self, val):
self.statusBar().showMessage(val)
def initUI(self):
self.toolbar = self.addToolBar('Tools')
self.setGeometry(30, 30, 30, 20)
self.setWindowTitle('Menubar')
self.show()
if __name__ == '__main__':
import sys
app = QApplication(sys.argv)
mainWindow = Example()
mainWindow.showFullScreen()
sys.exit(app.exec_())
问题是您的 class TicTacToe
没有直接或以其他方式从 QObject
继承,这意味着 Qt
无法使用它作为信号源。
尝试从 QGraphicsObject
继承...
class TicTacToe(QGraphicsObject):
def __init__(self):
super(TicTacToe, self).__init__()
只有从 QObject
继承的 class 才具有创建信号的能力,例如 QWidget
、QMainWIndow
、QGraphicsView
继承自 QObject
所以他们可以有信号。但是 QGraphicsItem
没有继承自 QObject
因为效率问题所以他们没有创建信号的能力。如果您想要 QObject
的项目,则必须使用 QGraphicsObject
。此外,项目有 paint()
方法,而不是 paintEvent()
.
class TicTacToe(QGraphicsObject):
def paint(self, painter, option, widget):
painter.setPen(Qt.black)
painter.drawLine(0,100,300,100)
def boundingRect(self):
return QRectF(0,0,300,300)
def mousePressEvent(self, event):
pos = event.pos()
# self.select(int(pos.x()/100), int(pos.y()/100))
self.update()
super(TicTacToe, self).mousePressEvent(event)
messageSignal = pyqtSignal(int)
如果您仍然想使用 QGraphicsItem
,一个可能的解决方法是创建一个 class 来负责通信并继承自 QObject
:
class Helper(QObject):
messageSignal = pyqtSignal(int)
class TicTacToe(QGraphicsObject):
def __init__(self, helper):
super(TicTacToe, self).__init__()
self.helper = helper
def paint(self, painter, option, widget):
painter.setPen(Qt.black)
painter.drawLine(0,100,300,100)
def boundingRect(self):
return QRectF(0,0,300,300)
def mousePressEvent(self, event):
pos = event.pos()
self.helper.emit(10)
# self.select(int(pos.x()/100), int(pos.y()/100))
self.update()
super(TicTacToe, self).mousePressEvent(event)
class MyGraphicsView(QGraphicsView):
def __init__(self):
super(MyGraphicsView, self).__init__()
scene = QGraphicsScene(self)
self.helper = Helper(self)
self.tic_tac_toe = TicTacToe(self.helper)
scene.addItem(self.tic_tac_toe)
scene.addPixmap(QPixmap("exit.png"))
self.setScene(scene)
def keyPressEvent(self, event):
key = event.key()
if key == Qt.Key_R:
self.tic_tac_toe.reset()
super(MyGraphicsView, self).keyPressEvent(event)
class Example(QMainWindow):
def __init__(self):
super(Example, self).__init__()
self.y = MyGraphicsView()
self.setCentralWidget(self.y)
self.helper.messageSignal.connect(self.messageSlot)
self.initUI()
def messageSlot(self, val):
self.statusBar().showMessage(val)
def initUI(self):
self.toolbar = self.addToolBar('Tools')
self.setGeometry(30, 30, 30, 20)
self.setWindowTitle('Menubar')
self.show()