我正在与您联系,社区,因为我已经用尽了所有有关如何完成这项工作的想法。
基本上,我正在做的是用相机检查护照并提取某些特征。
我需要方法send_data_to_the_server()
等到第一个函数check_passport()
给我期望的结果。
当捕获结果并为True
时,下一个功能(连接到服务器)可以继续进行。
我试图使其与time.sleep()
一起使用,因为它冻结了整个程序并变得无响应,我不得不杀死它。我发现它非常无效。
然后,我尝试将queue.Queue
与threading
模块一起使用。那也冻结了。
我的代码:
def check_passport(self, id, q): # <-- this function needs to finish and return True
self.validate_passport = NewUserValidationCamera()
self.root.add_widget(self.validate_passport)
if self.validate_passport._passport_passed: # this private variable will become True at some point
q.put((id, 'finished'))
# while not self.validate_passport._passport_passed:
# time.sleep(0.5)
# return True
def send_data_to_the_server(self): # this method waits until method "check_passport" returns True
...
...
def register_or_login(self):
if self.login_screen is False:
passport_passed = False
q = queue.Queue()
thread1 = threading.Thread(target=self.check_passport, args=(1, q))
thread2 = threading.Thread(target=self.send_data_to_the_server)
for thread in [thread1, thread2]:
thread.daemon = True
thread.start()
result = q.get()
print(result)
就像我说的那样,无论我使用time
还是threading
的解决方案都会冻结该应用程序。我也使用过while not self.validate_passport._passport_passed: time.sleep(0.5)
,但应用程序也没有响应。
您可能还需要知道的是self.validate_passport = NewUserValidationCamera()
因为它是由__init__()
方法触发的,所以启动了整个验证过程。
更新了代码以反映第二种方法的添加队列:
def register_or_login(self):
if self.login_screen is False:
passport_passed = False
q1 = queue.Queue()
q2 = queue.Queue()
thread1 = threading.Thread(target=self.create_a_validation_widget_and_check_passport, args=(1, q1))
thread2 = threading.Thread(target=self.send_data_to_the_server, args=(2, q2))
for thread in [thread1, thread2]:
thread.daemon = True
thread.start()
thread.join()
result1 = q1.get()
result2 = q2.get()
print(result1)
非常感谢任何帮助。
答案 0 :(得分:0)
我认为您可以像这样将Queue和thread.join一起使用
def __init__(self):
self.que = queue.Queue() # will use for get the data from the check_passport
self.thread1 = None # will use this attribute in send_data method to wait the check_passport
self.register_or_login()
def check_passport(self, id, q):
self.validate_passport = NewUserValidationCamera()
self.root.add_widget(self.validate_passport)
if self.validate_passport._passport_passed:
q.put((id, 'finished'))
return True
def send_data_to_the_server(self):
self.thread1.join() # The method waits for the thread1
print("check_passport: ", self.que.get())
...
def register_or_login(self):
if self.login_screen is False:
passport_passed = False
self.thread1 = threading.Thread(target=lamda id, q: self.que.put(self.check_passport(id, q)), args=(1, q))
# the lambda function puts the result of the check_passport in the self.que
thread2 = threading.Thread(target=self.send_data_to_the_server)
for thread in [self.thread1, thread2]:
thread.daemon = True
thread.start()
result = q.get()
print(result)
编辑: 在回答问题之前,我写了一个小例子,我想分享这个例子,以便您可以测试代码。
class test:
def __init__(self):
self.que = queue.Queue()
self.thread1 = threading.Thread(target=lambda arg1, arg2: self.que.put(self.func_1(arg1, arg2)), args=["hello", "world"])
self.thread1.start()
thread2 = threading.Thread(target=self.func_2)
thread2.start()
def func_1(self, foo_1, foo_2):
for bar in range(10):
print(bar)
time.sleep(1)
return "{} {}".format(foo_1, foo_2)
def func_2(self):
self.thread1.join()
result = self.que.get()
print(result)
答案 1 :(得分:0)
所以最后我要做的就是遵循@niclaslindgren自己的建议。我称其为“ KISS”方法或也称为“ Keep It Simple Stupid”。我还接受了@Steve关于使用全局变量的说法。我不是全局变量的忠实拥护者,但是它们在编程中确实有自己的位置。 下面为我做了窍门:
PASSPORT_VALIDATED = False
class NewUserValidationCamera(Image):
...
...
def update(self, dt):
...
...
if self.names[label] == 'ma' and self._passport_keyword_passed and self._gender_check_passed:
global PASSPORT_VALIDATED
PASSPORT_VALIDATED = True
class MainApp(App):
def __init__(self, **kwargs):
super(MainApp, self).__init__(**kwargs)
Clock.schedule_interval(self.check_for_True, 1.0)
...
...
def check_for_True(self, dt):
if PASSPORT_VALIDATED:
Clock.unschedule(self.check_for_True)
self.send_data_to_the_server()
def send_data_to_the_server(self):
...
...
def register_or_login(self):
if self.login_screen is False:
passport_passed = False
self.validate_passport = NewUserValidationCamera()
self.root.add_widget(self.validate_passport)