TLDR:当我使用线程函数作为另一个函数的装饰器时,如何检查线程是否还活着?
我正在使用 PyQt6 创建一个 GUI(如果选择不好,将接受其他建议)。 我的问题是当我单击“连接”按钮时,我想验证连接线程是否未运行。
由于代码太长,我用 ** 标记了相关内容
所以我在主init中创建了self.ecMaster属性,我尝试使用用@threaded装饰的is_alive方法来检查ecConnection是否已启动。
我收到错误:AttributeError:“function”对象没有属性“is_alive”
我应该怎样做才正确? 谢谢你
from threading import thread
import pysoem
import ecAPI as ec
from PyQt6.QtWidgets import *
from PyQt6.QtCore import *
from PyQt6.QtGui import *
class mainWindow(QMainWindow):
exitSignal = Signal() # Define the custom exit signal
def __init__(self,*args, **kwargs):
super().__init__(*args, **kwargs)
self.exitSignal.connect(app.quit)
self.central_widget = QWidget(self)
self.test_widget = QWidget(self)
self.modeSignal = ''
self.operatorSignal = ''
self.setCentralWidget(self.central_widget)
self.connectionWindowLayout()
**self.master = ec.ecMaster()**
def connectButtonClicked(self):
self.connect_button.clickable = False
# here i ran into trouble
**if self.master.ecConnection.is_alive:** # If thread is active
self.master.ecConnection.terminate()
logger.info('Connection thread was already active, terminated')
logger.info('Starting connection thread')
**self.master.ecConnection()** # Start connection thread
time.sleep(0.1)
if __name__ == '__main__':
logger = logging.getLogger(__name__)
logging.getLogger().setLevel(logging.INFO)
app = QApplication(sys.argv)
ModernStyle.apply(app)
window = mainWindow()
window.show()
sys.exit(app.exec())
import pysoem, logging
from threading import Thread
def threaded(fn):
# To use as decorator to make a function call threaded
def wrapper(*args, **kwargs):
thread = Thread(target=fn, args=args, kwargs=kwargs)
thread.start()
return thread
return wrapper
class ecMaster(pysoem.Master):
def __init__(self):
self.connectionSignal = 0
super().__init__()
def findAdapters(self):
nicName = 'PCIe' # Change based on PC --- 'PCIe
network_adapters = pysoem.find_adapters()
for adapter in network_adapters:
if nicName in str(adapter[1]):
networkAdapterID = adapter[0]
self.open(networkAdapterID)
logging.info('Found network adapter\n'+str(networkAdapterID))
return len(network_adapters)>0 # True if found
@threaded
def ecConnection(self):
if self.findAdapters():
print('Searching for EC devices ... ')
self.connectionSignal = self.config_init() # Initilize connection
if self.slaves:
print(f'Found {len(self.slave_list)} devices')
for i,slave in enumerate(self.slaves):
# ven = slave.sdo_read(0x1018, 1)
print(f'Found Device {slave.name},{slave.id},{slave.man}') #,{slave.sdo_read()}
logging.info(f'Found {self.connectionSignal} EC devices')
else:
logging.info('No salves were found')
print('Slaves not found')
else:
logging.warning('No network adapter found')
print('No network adapter found')
尝试去掉包装纸并只留下线。 网上搜了一下。 期望我装饰的函数具有 Thread 属性,但无法正确实现。
找到了解决办法。 self.master.ecConnection() 不是一个线程,而是一个函数。仅当运行它时,它才成为一个线程(由于@threaded装饰器)。 因此我添加了 con_thread = self.master.ecConnection() ,然后 con_thread 确实是一个线程对象,我可以访问 con_thread.is_alive()