python - PyQt:槽执行多次

标签 python pyqt signals slot

我有一个自定义小部件,用于在选项卡小部件中创建许多选项卡。在这个自定义小部件中,我有一个发送消息的按钮。该按钮连接到如下信号:

signal_mapper = QtCore.QSignalMapper()

self.send_btn.clicked.connect(self.sending_message)

sending_message 方法中,我获取数据并向线程发出信号以发送消息,如下所示:

QtCore.QObject.emit(
    signal_mapper,
    QtCore.SIGNAL("send_message"),
    message)

在发送线程中(时隙接收)

QtCore.QObject.connect(
    signal_mapper,
    QtCore.SIGNAL("send_message"),
    self.send_message
)

问题是当我有很多选项卡并且当我发送“一条”消息时,我发现它发送了创建的选项卡数量 * 消息(例如,如果我有 3 个选项卡,它会发送 3 条消息)。

编辑:

这是代码片段:

class Main(QtGui.QMainWindow):

    def __init__(self, user, user_lst, icon, connexion):
        super(Main, self).__init__()
        self.user_name = user
        self.user_lst = user_lst
        self.icon = icon
        self.connexion = connexion
        ...
        self.show()

    def init_ui(self):
        ...
        self.send_btn.clicked.connect(self.sending_message)
        ...


        self.chat_widget=ChatForm(self.user_name,self.user_lst,self.icon,self.connexion)
        self.tab_widget.addTab(self.chat_widget, self.my_actions.send_file_icon, "topic 1")

    def new_tab(self):
        chat_widget = ChatForm(self.user_name, self.user_lst, self.icon, self.connexion)
        self.tab_widget.insertTab(self.i, chat_widget, "topic")

    def sending_message(self):
        txt = str(self.line_edit.text())
        if txt != "":
            QtCore.QObject.emit(
                signal_mapper,
                QtCore.SIGNAL("send_message"),
                txt)

这里是发送线程:

class SendingThread(QtCore.QThread):
    def __init__(self, client_sock):
        super(SendingThread, self).__init__()
        self.client_socket = client_sock

    def run(self):
        # waiting user to send a message
        QtCore.QObject.connect(
            signal_mapper,
            QtCore.SIGNAL("send_message"),
            self.send_message, QtCore.Qt.UniqueConnection
        )

    def send_message(self, message):
        print("the message as sent", message)
        self.client_socket.send_msg(message)

最佳答案

所以,你的问题(大概)是你打开了 3 个选项卡,并且你将信号绑定(bind)到每个选项卡实例,因此所有未删除的选项卡将同时发出。可能会发生这样的事情:

(我的代码已经在PySide中完成,我将其更正为PyQt。核心原理仍然存在,尽管信号/槽语法略有不同)。

请注意,我如何将 clicked() 信号连接到 Signal.emit 槽,而是连接到 方法,这样我就可以设置调用 Signal.emit 时的条件。

'''Custom signal example'''

# QtTest is for artificial click events, ignore for implementation
from PySide import QtCore, QtGui, QtTest


class MyTabButton(QtGui.QPushButton):
    '''Custom widget for a tab'''

    signal = QtCore.Signal(str)

    def __init__(self, parent=None):
        super(MyTabButton, self).__init__()

        self.check_visible = True
        self.clicked.connect(self.send_message)

    def send_message(self):
        '''Only send message if object is clicked'''

        if not self.check_visible or self.isVisible():
            self.signal.emit('My message')


def printargs(message):
    '''Slot to print signal message'''

    print(message)



def main():
    '''On exec'''

    tabs = QtGui.QTabWidget()
    for _ in range(3):
        mytab = MyTabButton()
        mytab.signal.connect(printargs)
        tabs.addTab(mytab, 'My Tab {}'.format(_))

    # artificial mouse click at widget 0, the first tab
    # nothing should print
    QtTest.QTest.mouseClick(tabs.widget(0), QtCore.Qt.LeftButton)

    # only one tab should print
    tabs.widget(0).check_visible = False
    QtTest.QTest.mouseClick(tabs.widget(0), QtCore.Qt.LeftButton)


if __name__ == '__main__':
    APP = QtGui.QApplication([])
    main()

如果我运行此代码,则仅打印一个选项卡,并且仅打印第二个事件。此选项卡小部件可以通过 MyTabButton.check_visible 或小部件的可见性 (MyTabButton.show()) 进行控制。

关于python - PyQt:槽执行多次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36808611/

相关文章:

python - 将元组继承为列表

python - Python 命令 requests.post() 的 R 对应项是什么?

python - 通过在 Python 中使用 Paramiko 模块,我如何在 Linux 服务器上编辑文件?

python - 在 matplotlib 图中将鼠标限制在 Canvas 区域

python - 为什么 QIcon 功能不起作用? (PyQt4)

c - 如何在非规范模式下使用中断/终止信号?

python - 从异常中捕获有关已执行代码行的信息

python - 同时使用 GUI 和 CLI 与我的应用程序交互

python - 如何从 python 程序发送信号?

python - 如何让装饰器从被装饰函数访问变量?