2016-04-23 69 views
1

我有一个自定义小部件,用于在选项卡小部件中创建多个选项卡。在这个自定义小部件中,我有一个按钮来发送消息。在sending_message方法予取数据PyQt:插槽执行很多次

signal_mapper = QtCore.QSignalMapper() 

self.send_btn.clicked.connect(self.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) 
+0

您是否在QTabWidget的所有选项卡中初始化此信号,然后将其连接到某个通用插槽? 一个快速的解决方法可能是不将它连接到一个通用插槽('self.parent()。do_something()'),但将它连接到实例方法作为插槽,然后执行: 'if self。 isVisible():self.parent()。do_something()'。 这样,它只从当前可见的选项卡发出。 –

+0

我是pyqt的初学者,请问你能否给我一个具体的例子 –

+0

很少有问题(也可以,请不要通过FB联系我,我知道它是公开的,我愿意帮忙,但只是在这里请求SO )。 在'MainWindow'中定义'send_btn'而不是在每个单独的选项卡中定义?这很奇怪,我不确定它会如何表现,它应该由每个新标签重新排列。 –

回答

1

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

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

请注意,我如何将clicked()信号不连接到Signal.emit插槽,而是连接到method,然后允许我为打电话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())进行控制。

+0

现在还不清楚,请你给我多一点帮助。我通过添加代码片段来编辑我的问题。我希望你能帮助我。谢谢你。 –