2016-04-23 55 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

現在還不清楚,請你給我多一點幫助。我通過添加代碼片段來編輯我的問題。我希望你能幫助我。謝謝你。 –