修改下问题,之前的代码过于冗杂。先将测试代码贴在这里。
在该测试代码中,当这两句以如下方式排列时,voidSlot无法获得sender。但是当将这两句顺序调换,则两个槽函数均能获得sender()。
stageType.currentTextChanged[str].connect(self.loadStage)
connectBut.clicked.connect(self.voidSlot)
import sys,PySide6
from PySide6.QtWidgets import QApplication,QPushButton, QComboBox,QWidget,QVBoxLayout,QHBoxLayout
class Tab(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
stageType = QComboBox(self)
stageType.setObjectName('stageType')
stageType.addItem('阶段类型')
stageType.addItem('阶段类型1')
stageType.addItem('阶段类型2')
connectBut = QPushButton('连接',self)
connectBut.setObjectName('Connect ')
stageType.currentTextChanged[str].connect(self.loadStage)
connectBut.clicked.connect(self.voidSlot)
layout = QVBoxLayout(self)
selectLayout = QHBoxLayout()
selectLayout.addWidget(stageType)
controlLayout =QHBoxLayout()
controlLayout.addWidget(connectBut)
layout.addLayout(selectLayout)
layout.addLayout(controlLayout)
self.setLayout(layout)
@PySide6.QtCore.Slot()
def loadStage(self,stage_type):
print('Load Stage'+str(self.sender()))
@PySide6.QtCore.Slot()
def voidSlot(self):
print('voidSlot'+str(self.sender()))
if __name__ == '__main__':
app = QApplication(sys.argv)
tab = Tab()
tab.show()
sys.exit(app.exec_())
------下方为旧提问,可以无视---------
我一个PyQT初学者,最近在写这段代码时遇到,由connect连接的信号与槽,当信号被触发,进入槽的时候,无法获取sender()
其中关于这行代码 stageType.currentTextChanged[str].connect(self.loadStage)
,当改代码位于当前位置(见下部分代码),会导致后续的connectBut.clicked.connect(self.voidSlot)
,startBut.clicked.connect(self.voidSlot)
,cancelBut.clicked.connect(self.voidSlot)
中在,voidSlot
槽中无法获取sender()
。返回值为None
但是当这句话stageType.currentTextChanged[str].connect(self.loadStage)
位于上述三句话后时,连接的loadStage
槽与voidSlot
槽都能获取到sender()
。
但是在我的程序中,该段代码需要执行N次,因此如果放在上述三句话后,当执行第二次时,在第二个窗口中,voidSlot
依旧无法获得sender()
当前环境python=3.9 qt为Pyside6.2.1。
如果将环境变为pyqt5.15.6时,不会出现上述问题。
import sys,PySide6
from PySide6.QtWidgets import QApplication,\
QPushButton, QTabWidget, QComboBox, QLineEdit, QLabel
# 省略
class Tab(QTabWidget):
'''标签页'''
def __init__(self,statusBar,parent):
pass
# 省略
def initUI(self, tab, name):
'''
初始化一个标签页
'''
stageType = QComboBox(tab)
stageType.setObjectName('stageType')
stageType.currentTextChanged[str].connect(self.loadStage)
stageName = QComboBox(tab)
stageName.setObjectName('stageName')
stageNowLizhi = QLineEdit(tab)
stageNowLizhi.setObjectName('stageNowLizhi')
defaultStage = QPushButton('默认关卡',tab)
nowStatus = QLabel("这里用来显示现在的状态",tab)
connectBut = QPushButton('连接',tab)
connectBut.setObjectName('Connect '+name)
connectBut.clicked.connect(self.voidSlot)
startBut = QPushButton('开始行动',tab)
startBut.setObjectName('Start '+name)
startBut.clicked.connect(self.voidSlot)
cancelBut = QPushButton('停止行动',tab)
cancelBut.setObjectName('Cancel '+name)
cancelBut.clicked.connect(self.voidSlot).
# 省略
#以下为两个槽的函数
@PySide6.QtCore.Slot()
def loadStage(self,stage_type):
'''加载关卡数据'''
stageName = self.sender().parent().findChild(QComboBox,"stageName")
stageName.clear()
for line in self.stage_data:
if line[4] == stage_type:
stageName.addItem(str(line[0]))
@PySide6.QtCore.Slot()
def voidSlot(self):
'''默认用于显示哪个按钮被点击的槽'''
sender = self.sender()
self.statusBar.showMessage(sender.objectName()+' been clicked!',5000)
def __manual_enter(self):
"""
手动输入
"""
result = {}
frame_extraction_url = Config.KEDA_JK['autoFrameExtraction_url']
relay_url = Config.KEDA_JK['relay_url']
temp = 0
lading_no = None
lock_no = None
case_no = None
shipment_port = None
gn = None
while True:
try:
data,e = Messagebox.set_manual('提示', '提单号:', '锁号:', '箱号:', 500, 90, 10, "确定", button1="取消",
button2='强制抽帧', sh=self.lb_sh_num.text(), tdh=self.lb_tdh_num.text(),
xh=self.lb_xh_num.text(), domestic=True)
if data.get('tdh') and data.get('sh') and data.get('xh') and data.get('yes'):
if temp == 5:
Messagebox.set_message('提示', '连续错误五次,请取消或强制抽帧!', 150, 100, 14, '确定')
continue
data['tdh'] = data['tdh'].strip()
data['sh'] = data['sh'].strip()
data['xh'] = data['xh'].strip()
logger.info(f'shoudongshuru data:{data}')
logger.info(f"eee{e}")
logger.info(f'等待手动输入结果验证。。。')
lading_no = data['tdh']
lock_no = data['sh']
case_no = data['xh']
gn = e
shipment_port = Config.KEDA_JK['shipmentPort']
resend_ids = 1
compulsion = False
success, response_data = send_request_to_keda(lading_no, lock_no, shipment_port, case_no, gn, relay_url,
resend_ids, Config.lading_lock_img, Config.case_img,compulsion)
if success:
Config.shoudongyanzheng = 1
result['container_number'] = {"text": case_no, "result": "OK"}
result['tdh'] = {"text": lading_no, "result": "OK"}
result['sh'] = {"text": lock_no, "result": "OK"}
# result['license_plate'] = {"text": license_plate, "result": "OK"} # 更新车牌号结果
self.__update_result(result)
break
else:
result['container_number'] = {"text": case_no, "result": "NG"}
result['tdh'] = {"text": lading_no, "result": "NG"}
result['sh'] = {"text": lock_no, "result": "NG"}
# result['license_plate'] = {"text": license_plate, "result": "NG"} # 更新车牌号结果
self.__update_result(result)
temp += 1
elif data.get('tdh') and data.get('sh') and data.get('xh') and data.get('cz'):
if temp <= 1:
Messagebox.set_message('提示', '未达到强制开启抽帧条件,请继续手动验证!', 150, 100, 14, '确定')
else:
try:
gn = e
resend_ids = 1
compulsion = True
success, response_data = send_request_to_keda(lading_no, lock_no, shipment_port, case_no, gn,
relay_url,
resend_ids, Config.lading_lock_img,
Config.case_img, compulsion)
# send_flag = send_fakeAutodata(lading_no, lock_no, shipment_port, case_no, frame_extraction_url,compulsion,gn)
if success:
Config.shoudongyanzheng = 2
logger.info(f'开启强制抽帧成功,请检查后端')
break
else:
Config.shoudongyanzheng = 3
logger.info(f'开启强制抽帧失败,请检查后端')
break
except Exception as e:
logger.error(traceback.format_exc())
logger.error(e)
# 无论成功与否,都需要继续后续逻辑
elif data.get("cancel"):
Config.shoudongyanzheng = 0
logger.info(f'已取消')
success = False
break
else:
Messagebox.set_message('提示', '请全部输入!', 150, 100, 14, '确定')
except Exception as e:
logger.error(traceback.format_exc())
logger.error(e)为什么正常上传后端可以接收到数据强制抽帧就接收到None