我有一个自定义窗口小部件,用于在选项卡窗口小部件中创建许多选项卡。在这个自定义小部件中,我有一个发送消息的按钮。此按钮连接到这样的信号:
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)
答案 0 :(得分: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())来控制此选项卡小部件。