質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

解決済

3回答

20829閲覧

Pythonでsleepを使わずディレイを作りたい。

mathing

総合スコア19

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

0グッド

0クリップ

投稿2018/01/30 06:26

編集2018/01/31 16:17

質問をさせてください。
ボタンを押してから〇秒後に△処理を実行するというコードを書きたいと思っています。
sleep(〇)を使えば確かに実現できるのですがUIもフリーズしてしまうので避けたいです。
(例えばsleep(10)にした場合、10秒間は他のボタン処理等もできなくなると思うので。)

試したことは、kivy.Clock.CyClockbaseのschedule_onceです。
ですがやり方が間違っているのかエラーが出てしまい諦めました。
何か方法はありますか?お願いします。

ボタン「start_delay」を押してから3秒後に
self.ids["info"].text = "Done"
を実行する例としてお願いいたします。
イメージ説明
3秒後
イメージ説明

Python

1# -*- coding: utf-8 -* 2from time import sleep 3from kivy.app import App 4from kivy.uix.boxlayout import BoxLayout 5 6class MainFrame(BoxLayout): 7 8 def __init__(self, **kwargs): 9 super(MainFrame, self).__init__(**kwargs) 10 11 def start_delay(self): 12 sleep(3) 13 self.ids["info"].text = "Done" 14 15 16class delay_test(App): 17 def build(self): 18 return MainFrame() 19 20 21if __name__ == "__main__": 22 delay_test().run()

KV

1#:kivy 1.10.0 2<MainFrame>: 3 orientation: "vertical" 4 Label: 5 id: info 6 text: "not yet" 7 Button: 8 text: "Start delay" 9 on_press: root.start_delay()

追記 2018/2/1
期待した結果が得られたコード

Python

1# -*- coding: utf-8 -* 2from kivy.app import App 3from kivy.lang import Builder 4from kivy.uix.boxlayout import BoxLayout 5from kivy.clock import Clock 6Builder.load_string(""" 7<MainFrame>: 8 orientation: "vertical" 9 Label: 10 id: info 11 text: "not yet" 12 Button: 13 text: "Start delay" 14 on_press: root.start_delay() 15""") 16 17class MainFrame(BoxLayout): 18 19 def __init__(self, **kwargs): 20 super(MainFrame, self).__init__(**kwargs) 21 22 def start_delay(self): 23 def callback(dt): 24 self.ids["info"].text = "Done" 25 Clock.schedule_once(callback, 3) 26 27 28class delay_test(App): 29 def build(self): 30 return MainFrame() 31 32 33if __name__ == "__main__": 34 delay_test().run()

上のコードを別のやり方でやろうとしたコード
結果、エラーで強制終了。

Python

1# -*- coding: utf-8 -* 2from kivy.app import App 3from kivy.lang import Builder 4from kivy.uix.boxlayout import BoxLayout 5from kivy.clock import Clock 6Builder.load_string(""" 7<MainFrame>: 8 orientation: "vertical" 9 Label: 10 id: info 11 text: "not yet" 12 Button: 13 text: "Start delay" 14 on_press: root.start_delay() 15""") 16 17class MainFrame(BoxLayout): 18 19 def __init__(self, **kwargs): 20 super(MainFrame, self).__init__(**kwargs) 21 22 def start_delay(self): 23 Clock.schedule_once(self.change_text, 3) 24 25 def change_text(self): 26 self.ids["info"].text = "Done" 27 28class delay_test(App): 29 def build(self): 30 return MainFrame() 31 32 33if __name__ == "__main__": 34 delay_test().run()

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

コメント欄だとMarkdown使えないのでこっちに書きますね

python3

1 2from kivy.clock import Clock 3 4class MainFrame(BoxLayout): 5 6 def start_delay(self): 7 def callback(dt): 8 self.ids["info"].text = "Done" 9 Clock.schedule_once(callback, 3)

これでうまくいくと思いますよ

投稿2018/01/31 14:10

gottadiveintopy

総合スコア736

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

mathing

2018/01/31 16:22

gottadiveintopyさん。 ありがとうございます。うまくいきました!gottadiveintopyさんのコードの様なものは初めて見ました。 def 〇〇()の中にさらにdef △△()とありますが、これは関数の中にさらに関数を記述しているということなのでしょうか?私が最初にやったやり方を追記しておきました。追記したやりかた(関数を別々に書く)だとはやりうまくいかないのでしょうか?
gottadiveintopy

2018/02/01 09:02

def start_delay(self): Clock.schedule_once(self.change_text, 3) の中の "self.change_text" と書いた時点でchange_textメソッドの仮引数selfに渡る引数が決まっているので、dtは第二引数として渡るのですが、そのchange_textメソッドは引数を一つしかとらないのでdtを受け取ることができずエラーになります。 この時、多分 "○○ takes exactly ○ arguments but ○ were given"みたいなエラーが出るのですが、これがメソッドに渡す引数の個数が間違っている時のエラーです。 self.change_textで動くようにするには以下のように、2つの引数を受け取るメソッドにすればいいです。 def change_text(self, dt): self.ids["info"].text = "Done"
mathing

2018/02/01 09:52

ご丁寧な説明をいただき、ありがとうございます。 第2引数としてdtを加えると確かに期待した結果が得られました。 最後の質問なのですが、dtを加えた理由はClock.schedule_once(self.change_text, 3)の○秒後を示す"3"のためのでしょうか?
gottadiveintopy

2018/02/01 10:42

schedule_onceの形式(引数の位置や個数)は関係無いです。 https://pyky.github.io/kivy-doc-ja/api-kivy.clock.html ドキュメントを読んだのなら分かると思いますが、schedule_onceに渡す関数は引数に経過時間(こちらがお願いした3秒ではなく実際に経った時間)を渡されて呼ばれるので、それを受け取れるようになってないといけません。
mathing

2018/02/02 08:36

ありがとうございます。 初心者の私はまず専門用語との睨めっこになりそうです。 1つ1つ確かめながら努力していきたいと思いました。 本当にありがとうございました。
guest

0

ベストアンサー

python

1from threading import Timer 2 3Timer(3, setattr, args=(self.ids["info"], "text", "Done")).start()

で上手く行きませんか?

上記の検証コード

python

1from threading import Timer 2from unittest import mock 3 4obj = mock.MagicMock() 5Timer(3, setattr, args=(obj, "text", "Done")).start() 6# しばらくしてから 7print(obj.text)

投稿2018/01/30 06:44

編集2018/01/30 06:48
YouheiSakurai

総合スコア6142

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

mathing

2018/01/30 06:55

YouheiSakuraiさん。 ご回答ありがとうございます。 UIのフリーズ無しで実現できました!ありがとうございます! 理想の結果が得られました。 threadingについてこれから調べたいと思います。 本当にありがとうございました。
guest

0

kivy.clock.Clock の schedule_once() で できると思いますよ。

kivyは確かマルチスレッド未対応だったはずなので、やるなら複数のスレッドが同時にkivyを触らないような工夫が要ると思います。

投稿2018/01/31 10:19

gottadiveintopy

総合スコア736

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

mathing

2018/01/31 12:16

gottadiveintopyさん。 アドバイスありがとうございます。最初はschedule_onceでやろうとしたのですが上手く記述することができず、他の回答者さんに教えていただいた別のやりかたで実現させました。 その方法がThreadingのTimerを使う方法なのですが、実際に実現できたのでKivyはマルチスレッド対応なのではないでしょうか?私自身マルチスレッドという言葉を知ったのは昨日なのでもしかしたら私の認識が間違っているかもしれませんが・・・。 https://teratail.com/questions/111309 関連した質問をもう1つしたものがこちらになります。
gottadiveintopy

2018/01/31 13:17

マルチスレッド未対応だからと言って、マルチスレッド時に必ず問題を起こすわけではないです。問題なく動くかもしれないし動かないかもしれない、問題が表面に現れていないだけかもしれないので。ただ実はマルチスレッド未対応という記述を見たのは1年以上前なので、変わってたらごめんなさい。 ただ、仮にマルチスレッド対応だったとしてもschedule_once()で済むのならそれに越したことはないですよ。スレッドをつくる事自体が高つく処理のはずなので。
mathing

2018/01/31 13:28

なるほど。確かにその通りですね。 問題は私がschedule_once()を使った記述をできなかったということです。 その後も調べてみたのですが分からず、ThreadingのTimerで代用できているのでそのままにしてしまいました。もしよろしければ今回の質問をschedule_once()を使った解決方法で教えていただけないでしょうか?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問