PyQt6 自定义信号与槽连接
我有一个按钮,它是一个单独的类,还有一个主窗口类。在主窗口里,有两个输入框(QLineEdit)。我想在点击按钮时获取这两个输入框里的文本,并对它们进行处理。处理的逻辑应该放在按钮的类里,因为我想尝试使用信号和槽的连接。按钮类会接收来自输入框的文本,并以某种方式返回处理后的文本。返回的文本会显示在一个标签(QLabel)上。目前文本没有变化,尽管文本已经发出了处理的信号。然后它应该再发回去,但现在不工作。
import sys
from PyQt6.QtWidgets import QApplication, QPushButton, QVBoxLayout, QLabel, QLineEdit, QWidget
from PyQt6.QtCore import pyqtSignal as Signal, pyqtSlot as Slot
class ButtonWidget(QPushButton):
accepted_text = Signal(str, str)
def __init__(self):
super().__init__()
self.setText("Accept Text")
@Slot(str, str)
def accept_text(self, text1, text2):
text1 = text1.upper()
text2 = text2.title()
self.accepted_text.emit(text1, text2)
class MainWindow(QWidget):
pushed_text = Signal(str, str)
def __init__(self):
super().__init__()
layout = QVBoxLayout()
self.setLayout(layout)
self.line1 = QLineEdit(placeholderText="enter text")
self.line2 = QLineEdit(placeholderText="enter text")
self.button_widget = ButtonWidget()
self.label = QLabel("")
layout.addWidget(self.line1)
layout.addWidget(self.line2)
layout.addWidget(self.button_widget)
layout.addWidget(self.label)
self.pushed_text.connect(self.button_widget.accept_text)
self.button_widget.clicked.connect(self.change_label)
self.show()
def change_label(self):
text1 = self.line1.text()
text2 = self.line2.text()
self.pushed_text.emit(text1, text2)
self.label.setText(text1 + " " + text2)
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MainWindow()
sys.exit(app.exec())
我尝试将按钮类中的 accept_text()
函数与主窗口类中输入框的 pushed_text
信号连接起来。accept_text()
函数应该以某种方式返回处理后的文本。
它应该是 STACK Overflow,而不是 stack overflow。有没有什么方法可以正确地在类之间连接信号和槽?
1 个回答
0
我想我大概弄明白了,但过程有点乱。也许有更好的方法。这个事情真的很让人困惑,如果你知道更好的方法,请告诉我。我做了以下更改:
class ButtonWidget(QPushButton):
accepted_text = Signal(str, str)
returned_text = Signal(str, str)
def __init__(self):
super().__init__()
self.setText("Accept Text")
self.accepted_text.connect(self.accept_text)
@Slot(str, str)
def accept_text(self, text1, text2):
text1 = text1.upper()
text2 = text2.title()
self.returned_text.emit(text1, text2)
我给 ButtonWidget 添加了一个新的信号 returned_text。我把 accepted_text 信号和 accept_text 这个函数连接起来。现在这个函数会发出 returned_text 信号。
在 MainWindow 窗口里,我删除了 pushed_text 信号,并添加了以下代码:
self.button_widget.returned_text.connect(self.update_label)
self.button_widget.clicked.connect(self.change_label)
self.show()
def update_label(self, text1, text2):
self.label.setText(text1 + " " + text2)
def change_label(self):
text1 = self.line1.text()
text2 = self.line2.text()
self.button_widget.accepted_text.emit(text1, text2)
我把 returned_text 信号和 update_label 函数连接起来。按钮点击事件仍然连接着 change_label 函数。在这个函数里,我们获取想要更改的元素,并发出 accepted_text 信号,这个信号又连接着 ButtonWidget 里的 accept_text 函数。
现在它的工作方式正是我想要的那样。
这是完整的代码:
import sys
from PyQt6.QtWidgets import QApplication, QPushButton, QVBoxLayout, QLabel, QLineEdit, QWidget
from PyQt6.QtCore import pyqtSignal as Signal, pyqtSlot as Slot
class ButtonWidget(QPushButton):
accepted_text = Signal(str, str)
returned_text = Signal(str, str)
def __init__(self):
super().__init__()
self.setText("Accept Text")
self.accepted_text.connect(self.accept_text)
@Slot(str, str)
def accept_text(self, text1, text2):
text1 = text1.upper()
text2 = text2.title()
self.returned_text.emit(text1, text2)
class MainWindow(QWidget):
def __init__(self):
super().__init__()
layout = QVBoxLayout()
self.setLayout(layout)
self.line1 = QLineEdit(placeholderText="enter text")
self.line2 = QLineEdit(placeholderText="enter text")
self.button_widget = ButtonWidget()
self.label = QLabel("")
layout.addWidget(self.line1)
layout.addWidget(self.line2)
layout.addWidget(self.button_widget)
layout.addWidget(self.label)
self.button_widget.returned_text.connect(self.update_label)
self.button_widget.clicked.connect(self.change_label)
self.show()
def update_label(self, text1, text2):
self.label.setText(text1 + " " + text2)
def change_label(self):
text1 = self.line1.text()
text2 = self.line2.text()
self.button_widget.accepted_text.emit(text1, text2)
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MainWindow()
sys.exit(app.exec())