ПРОБЛЕМА
У меня есть все oop, которые в каждом отрывке отображают всплывающее окно. Я назову это popup_A. В l oop есть условие, при котором он запускает вместе другое всплывающее окно и метод в потоке. Это второе всплывающее окно я называю popup_B. Проблема в том, что popup_B он показывает, но сразу после этого popup_A отображается поверх popup_B, полностью закрывая его. Чтобы лучше представить себе представление о потоке:
def myFun:
if condition1:
method1
if condition2:
method2
if condition3:
show popup_B
thread method3
thread popup_A
def popup_A:
do something
display message_A
call myFun
def popup_B:
display message_B
CODE Метод, участвующий в цикле:
def goForward(self):
if self.header == "someTask":
if "tasks" in self.data: # check if the request has "tasks" in the body
if self.counter < len(self.data["tasks"]): # check the counter
self.code = self.data["tasks"][self.counter].get("code")
action = self.data["tasks"][self.counter].get("actionDescription")
if "myCondition" in str(action):
#set the popup structure
self.popup_B = ActivityBox(self)
self.popup_B.open()
# run the method in a thread
t1 = threading.Thread(target = timeConsumingMethod)
t1.start()
# dismiss the popup ActivityBox
self.popup_B.dismiss()
# call popup_A in thread
t3 = threading.Thread(target = self.popup_A)
t3.start()
def do(self):
self.counter = self.counter + 1
self.popup.dismiss()
self.goForward()
def cancel(self):
self.counter = self.counter + 1
self.popup.dismiss()
self.goForward()
def popup_A(self):
self.popup = MessageBox(self)
self.popup.open()
Структура всплывающих окон ActivityBox и MessageBox в the Builder.load_string()
:
<MessageBox>:
size_hint: 1, .7
auto_dismiss: False
title: "MessageBoxTitle"
title_align: "center"
title_size: 30
BoxLayout:
orientation: "vertical"
Label:
font_size: '30sp'
text: "MessageBoxLabel"
BoxLayout:
orientation: "horizontal"
spacing: 10
size_hint: 1, .5
Button:
font_size: 50
background_color: 0,204,0,1
text: "CONFIRM"
on_press:
self.disabled = True
self.background_color = 0,255,0,1
app.do()
root.dismiss()
Button:
font_size: 50
background_color: 204,0,0,1
text: "CANCEL"
on_press:
self.background_color = 255,0,0,1
app.cancel()
root.dismiss()
<ActivityBox>:
size_hint: 1, .7
auto_dismiss: False
title: "ActivityBoxTitle"
title_align: "center"
title_size: 30
BoxLayout:
orientation: "vertical"
Label:
font_size: '30sp'
text: "ActivityBoxLabel"
BoxLayout:
orientation: "horizontal"
spacing: 10
size_hint: 1, .5
ОБЪЯСНЕНИЕ КОДА Компонентами основного l oop являются goForward
и popup_A. При каждом проходе l oop появляется popup_A, вызываемое в потоке. Затем popup_A перезванивает goForward
. Если условие «работа» в goForward
выполняется, появляется всплывающее окно «работа в процессе». Popup_B запускается вместе с методом в потоке, иначе Kivy не отображает всплывающее окно (блокировка GUI).
РЕЗУЛЬТАТЫ
До сих пор я пробовал использовать:
- Запуск popup_B в потоке
t1 = threading.Thread(target = self.popup.open)
: popup_A закрывает popup_B. - Использование потока
.join()
: popup_A появляется, а popup_B нет, .join ( ) игнорирует его. - Запустите popup_B и
timeConsumingMethod
вместе в потоке: popup_A появляется, а popup_B нет. - Запустите
timeConsumingMethod
как процесс: появляется popup_A но popup_B нет, программа зависает. - Использование
mutex = threading.Lock()
для блокировки потока с помощью popup_B: popup_A появляется поверх popup_B. Также GUI искажается. - Запустите popup_A не в потоке и запустите popup_B и
timeConsumingMethod
вместе в потоке: popup_A появляется поверх popup_B.
ВОПРОС
Popup_A может появиться только после того, как метод в потоке завершился и popup_B было закрыто. Как я могу запретить popup_A закрывать popup_B?
Я просмотрел сообщения ниже, но не нашел решения.
--- ОБНОВЛЕНИЕ 20200715 ----- -------------------------------------------
В коде я переименовал всплывающее окно «в процессе выполнения» в popup_B и popup2 в popup_A для лучшего понимания.
--- ОБНОВЛЕНИЕ 20200716 ------------------------------------------------ -
Я изменил код, используя Clock.schedule_once
для step2
(поток для popup_A
и step3
(поток для timeConsumingMethod
и popup_B
). popup_B
идет вверх, но popup_A
закрывает его до тех пор, пока последний popup_A
не будет отключен кнопкой. Чтобы дождаться, пока timeConsumingMethod
закончит sh без запуска popup_A
, я использую while loop
. Код ниже:
def goForward(self):
if self.header == "someTask":
if "tasks" in self.data: # check if the request has "tasks" in the body
if self.counter < len(self.data["tasks"]): # check the counter
self.code = self.data["tasks"][self.counter].get("code")
action = self.data["tasks"][self.counter].get("actionDescription")
if "myCondition" in str(action):
self.returnStatus = 1 # set status
#the two rows below give the same result
#self.popup_B = ActivityBox(self)
#self.popup_B.open()
Clock.schedule_once(self.step3)
# run the method in a thread
t1 = threading.Thread(target = self.step1)
t1.start()
while self.returnStatus != 0:
time.sleep(1)
Cloch.schedule_once(self.step2)
def step1(self):
ts1 = threading.Thread(target = self.timeConsumingMethod)
ts1.start()
ts1.join()
self.returnStatus = 0 # change status when over
return(self.returnStatus)
def step2(self, *args):
ts2 = threading.Thread(target = self.popup_A)
ts2.start()
def step3(self, *args):
#set the popup structure
self.popup = ActivityBox(self)
self.popup.open()
def popup_A(self):
self.popup = MessageBox(self)
t3 = threading.Thread(target = self.popup.open)
t3.start()
def do(self):
self.counter = self.counter + 1
self.popup.dismiss()
self.goForward()
def cancel(self):
self.counter = self.counter + 1
self.popup.dismiss()
exit()
- Правильный способ реализации всплывающего окна загрузки в приложении kivy
- Kivy: отклонить одно всплывающее окно из другого всплывающего окна
- Часы Kivy и всплывающее окно