Ich habe eine einfache Primzahl-Checker, die Speicherprobleme bei 16 Ziffern plus lief, wenn ich auf dem mobilen Gerät lief. Ich dachte mir, ich könnte das beheben, indem ich den Primzahlprüfer in einem separaten Thread als GUI ausführen lasse. Durch andere Beispiele zu schauen, hat mir nicht geholfen, aber ich habe stattdessen zufällige Teile aus verschiedenen Beispielen hinzugefügt. Wie auch immer, hier ist der Code.Wie starte ich einen neuen Thread, um Berechnungen durchzuführen, um Speicherfehler in der GUI von kivy zu vermeiden?
from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.widget import Widget
from kivy.uix.textinput import TextInput
from kivy.uix.button import Button
from kivy.properties import ObjectProperty
from kivy.clock import mainthread
from kivy.lang import Builder
from numpy import remainder, sqrt, floor
from datetime import datetime
import threading
Builder.load_string('''
<MainScreen>:
number: number_input
check: check_button
answer: answer
time: time
canvas:
Color:
rgba: .2, .2, .5, .5
Rectangle:
pos: self.pos
size: self.size
# answer button
Color:
rgba: .5, .8, .8, .5
Rectangle:
pos: 0, root.height/3
size: root.width/2, root.height/10
# time button
Color:
rgba: .2, .5, .5, .5
Rectangle:
pos: 0, root.height/6
size: root.width, root.height/10
TextInput:
id: number_input
pos: root.width/4, 2 * root.height/3
size: root.width/2, root.height/10
multiline: False
input_filter: 'int'
hint_text: 'Enter number'
write_tab: False
Button:
id: check_button
pos: root.width/2, root.height/3
size: root.width/2, root.height/10
text: 'Check'
on_press:
root.start_second_thread()
Label:
id: answer
text: 'Answer'
pos: 0, root.height/3
size: root.width/2, root.height/10
Label:
id: time
pos: 0, root.height/6
size: root.width, root.height/10
text: 'Time taken'
''')
class MainScreen(Widget):
number = ObjectProperty(None)
check = ObjectProperty(None)
answer = ObjectProperty(None)
time = ObjectProperty(None)
def start_second_thread(self):
thread2 = threading.Thread(target=self.prime_checker)
thread2.start()
#thread2.join()
print(threading.activeCount())
def prime_checker(self, *args):
ans = ''
now = datetime.now()
if self.number.text == '':
#self.answer.text = 'No number entered'
ans = 'No number entered'
end = datetime.now() - now
#self.time_checker(end)
elif len(self.number.text) > 17:
#self.answer.text = 'Too big for now'
ans = 'Too big for now'
end = datetime.now() - now
#self.time_checker(end)
else:
numb = int(self.number.text)
upper_limit = int(floor(sqrt(numb)))
tested = False
if numb < 2:
#self.answer.text = 'Not Prime'
ans = 'Not Prime'
end = datetime.now() - now
#self.time_checker(end)
elif numb == 2:
#self.answer.text = 'Prime'
ans = 'Prime'
end = datetime.now() - now
#self.time_checker(end)
elif numb % 2 == 0:
#self.answer.text = 'Not Prime, 2'
ans = 'Not Prime, 2'
end = datetime.now() - now
#self.time_checker(end)
else:
for i in range(3, upper_limit, 2):
#if numb % i == 0:
if remainder(numb, i) == 0:
#self.answer.text = 'Not Prime, {}'.format(i)
ans = 'Not Prime, {}'.format(i)
tested = True
end = datetime.now() - now
#self.time_checker(end)
break
if tested == False:
#self.answer.text = 'Prime'
ans = 'Prime'
end = datetime.now() - now
#self.time_checker(end)
self.update_main_thread(ans, end)
def time_checker(self, some_time):
some_time = 'This took {0} seconds and {1} milliseconds'.format(some_time.seconds, float(some_time.microseconds)/1000)
#self.time.text = some_time
@mainthread
def update_main_thread(self, ans, tim):
self.answer.text = ans
tim = 'This took {0} seconds and {1} milliseconds'.format(tim.seconds, float(tim.microseconds)/1000)
self.time.text = tim
class PrimeNumberCheckerApp(App):
def build(self):
return MainScreen()
if __name__ == '__main__':
PrimeNumberCheckerApp().run()
Ich bin sicher, dass eine Tonne von Dingen gibt es ich besser machen kann, auf die Vorschläge sind willkommen; Am wichtigsten ist mir jedoch, warum die Zeile print (threading.activeCount()) 1 statt 2 ausgibt. Danke.
Sind Sie sicher, dass der Thread nicht einfach fertig ist, bevor Sie zur Druckanweisung gelangen? – Natecat
Nun, ich denke, ich habe die Print-Anweisung nie an den richtigen Ort gebracht. Ich habe es einen Tag lang versucht und nach dem Lesen Ihres Kommentars und dem Verschieben der Druckanweisungspaarzeilen tut es jetzt, was ich wollte. Vielen Dank. Auf eine Randnotiz, werde ich Frage schließen, wenn ich herausfinden, wie. – pizz