将信号连接到 PyQt 中类之间的插槽



>目的是将顶级TicTacToe的信号与QMainWindow类连接起来。

它抛出一个错误: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_())

只有继承自QObject的类才能创建信号,例如QWidgetQMainWIndowQGraphicsView继承自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,一个可能的解决方法是创建一个负责通信并从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()  

问题是你的类TicTacToe不会直接或间接地继承QObject这意味着它不能被Qt用作信号源。

尝试从QGraphicsObject继承...

class TicTacToe(QGraphicsObject):
def __init__(self):
super(TicTacToe, self).__init__()

最新更新