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

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

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

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

1106閲覧

observeInBackgroundを使用してもexitが実行されない

minagann

総合スコア8

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2020/08/11 05:42

前提・実現したいこと

1.whileループの終了条件は処理を始めてから3時間後に終了する。
そのため監視する時間も3時間(10800秒)にしている
2 whileループしながらの監視ともあって多少の負荷を考慮し1分に1回のスキャン頻度にしている
3 画像を検知したらSikulixごと落としてプログラムを終了させる

該当のソースコード

import sys reload(sys) sys.setdefaultencoding('utf-8') Settings.ObserveScanRate = 0.016 #1分に1回スキャンする設定 reg = (Region(1020,0,900,1080)) reg.onAppear("1597108433229.png",test)#対象の画像が出たら 関数testを実行する reg.observeInBackground(10800) #他の処理をさせつつバックグラウンドで3時間監視 cnt = 0  def test(event): print(u"発見した") sys.exit() while True: wait(1) print(cnt) cnt +=1

試したこと

上記のは確認のためにつくりました
この場合、対象の画像をregion範囲内にすでに出しておき
1秒づつカウントしていくことで1分後のスキャンに画像を検知しプログラムが終わると思っていたんですけど
終わらずにカウントしつづけていきました・・・

補足情報(FW/ツールのバージョンなど)

SikulixIDE-2.0.4

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

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

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

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

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

guest

回答1

0

ベストアンサー

onAppear()を使って、メインの処理とは別にバックグラウンドで並列ができるということは、メインの処理とは別のスレッドで処理が動いているということです。onAppear()のハンドラに指定しているtest()も別スレッド側の処理ですから、test()の中でexit()を使っても、メインの処理は影響を受けません。

対策としては、global変数を使って、メインと別スレッド間で情報の受け渡しをするのが手っ取り早いでしょう。test()の中でexit()を使う代わりに、メイン側で定義した変数に値を設定して、メインのwhileの中でその変数を監視するようにし、変数が変化したらwhileからbreakすればいけるはずです。

【補足】
pythonにはsys.exit()がありますが、SikuliXの内部初期化のためにexit()を使いましょう。

投稿2020/08/11 07:25

maohara

総合スコア80

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

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

minagann

2020/08/11 07:51 編集

global変数に関してはまだ勉強不足で概念やどう実装したらいいのか分からないので勉強します; 他にwhile内で if reg.exists(”検知する画像"):  breakとすれば 出てきた画像を検知しbreakさせて3時間経過させなくても強制終了させることもできますかね? global変数のほうが当初の目的に合致しそうではあるんですけども while文の中には if reg.exists(”画像"): 該当処理 if reg.exists(”画像"):   該当処理 if reg.exists(”画像"):   該当処理 とその都度その都度画面を見て処理するループなので割り込みに近い形でbreakさせられるのかなと
maohara

2020/08/11 08:35

whileの中ではonAppearで監視する画像とは関係しない操作を行うときに、onAppearを使うのが通常ですが、目的が達成できればやり方にこだわらなくていいと思います。 global変数の使い方は簡単なので、ネットで探して下さい。
minagann

2020/08/11 08:41

わかりました、いつもありがとうござます
minagann

2020/08/12 01:14 編集

import sys reload(sys) sys.setdefaultencoding('utf-8') Settings.ObserveScanRate = 0.016 reg = selectRegion() global end end = 0 # イベントハンドラを作成 def test(event): # イベントの種類を取得 global end end =+ 1 # イベントを指定 reg.onAppear("1597130308943.png", test) # 指定秒数監視スタート reg.observeInBackground(10800) while True:   if reg.exists(”画像"):      少し長い処理    if reg.exists(”画像"):      少し長い処理   if end == 1:     break これだと 前提 while True:     if reg.exists(”画像"):      少し長い処理 をずっと続けている状態で 1.対象の画像が表示される 2.1分周期のスキャンに検知しglobal変数 endに1を入れる 3.whileループ内のif end == 1:           break   で抜けて終了 ってことだと思うんですけど 2と3の間に少し長い処理をやっているとそれが終わるまでif end == 1:に入れないですよね? 1で検知した瞬間にプログラムを終了させることはできないんですかね?
minagann

2020/08/12 01:16

while文とdef test(event)は一括りではなく testにexitをいれてもtestが終わるだけ?なのはわかりました
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問