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

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

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

OpenCV(オープンソースコンピュータービジョン)は、1999年にインテルが開発・公開したオープンソースのコンピュータビジョン向けのクロスプラットフォームライブラリです。

Python 3.x

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

Tkinter

Tkinterは、GUIツールキットである“Tk”をPythonから利用できるようにした標準ライブラリである。

Python

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

解決済

Tkinterでthreadingを使用するとOpenCVのウィンドウが閉じてしまう

nkfrom_asu
nkfrom

総合スコア8

OpenCV

OpenCV(オープンソースコンピュータービジョン)は、1999年にインテルが開発・公開したオープンソースのコンピュータビジョン向けのクロスプラットフォームライブラリです。

Python 3.x

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

Tkinter

Tkinterは、GUIツールキットである“Tk”をPythonから利用できるようにした標準ライブラリである。

Python

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

1回答

0評価

0クリップ

346閲覧

投稿2022/03/10 02:22

編集2022/03/22 05:52

前提・実現したいこと

Tkinterでサイコロを振るアプリを作成しています。
ボタンを押すと乱数を生成し、それに対応したGIFが流れるというものです。
サイコロが転がり、目が決定するという、ループなしで1秒のGIFを6つ用意しています。
ボタンの上にあるEntryから回数を指定します (指定しない場合は1回) 。
GIFの表示にはOpenCVを使用しています。

発生している問題

等確率かどうかを調べるため、合計回数と平均をTkinterのウィンドウに表示しました。
そこで発生した、GIFの表示が終わるまで更新されない問題を解決するため、threadingを使用したのですが、1度実行するとOpenCVのウィンドウが閉じてしまいます。

該当のソースコード

Python

import tkinter import cv2 import random import threading rng_sum, qty = 0, 0 fnt = ("Helvetica", 10) def animated_gif(): rng = random.randint(1, 6) #乱数の生成 gif = cv2.VideoCapture("1~6/{}.gif".format(rng)) #GIFファイルの読み込み fps = gif.get(cv2.CAP_PROP_FPS) images = [] #画像をリストに追加 a = 0 while True: is_success, img = gif.read() if not is_success: break images.append(img) a += 1 cv2.namedWindow("OpenCV", cv2.WINDOW_AUTOSIZE) #ウィンドウに表示 for b in range(len(images)): cv2.imshow("OpenCV", images[b]) cv2.waitKey(int(1000/fps)) cv2.moveWindow('OpenCV', 100, 100) global rng_sum, qty #平均を求める rng_sum += rng qty += 1 avg = rng_sum / qty la1 = tkinter.Label(root, text = "total number of times: {}".format(qty), fg = "white", bg = "green", font = fnt) la1.place(x = 0, y = 45) #今は config() で更新しています la2 = tkinter.Label(root, text = "average: {:.2f}".format(avg), fg = "white", bg = "green", font = fnt) la2.place(x = 0, y = 62) #同上 def bu_on(): thread1 = threading.Thread(target = work1) thread1.start() def work1(): #回数の指定 c = en.get() if c == "": animated_gif() else: num = int(c) for d in range(num): animated_gif() root = tkinter.Tk() root.geometry("180x84") #サイズ root.geometry("+95+100") #位置 root.attributes("-topmost", True) #最前面に表示 root.configure(bg="green") en = tkinter.Entry(width = 30) en.pack() en.bind("<Return>", lambda event: bu_on()) bu = tkinter.Button(text = "Roll", width = 30, command = bu_on) bu.pack() root.mainloop()

試したこと

threadingにする前はウィンドウが閉じることはありませんでした。buのcommandをwork1にすると同じ状況になります。

※追記
同じ状況ではありませんでした。buのcommand、またはen.bindのlambdaをwork1にし、work1を1度でも実行すると、その後はbu_onを実行してもウィンドウが閉じることはありませんでした。根本的な解決には至っていないため、引き続き回答よろしくお願いします。

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

Python 3.10.2
初めてのアプリ作成なので見にくい部分もあると思いますが、よろしくお願いします。

追記

Python

import tkinter import random root = tkinter.Tk() photo = tkinter.PhotoImage(file = "1~6/1.gif") gif_index = 0 start_flag = False def times(t): global start_flag i = int(en.get() or 1) if start_flag and t <= i: roll() root.after(1200, times, t + 1) bu1.config(state = "disabled") else: bu1.config(state = "normal") #なくてもいい? start_flag = False def start(): global start_flag start_flag = True times(1) def stop(): global start_flag start_flag = False def roll(): global photo rng = random.randint(1, 6) photo = tkinter.PhotoImage(file="1~6/{}.gif".format(rng)) #la["image"] = photo la.config(image = photo) gif() def gif(): global gif_index try: photo.config(format="gif -index {}".format(gif_index)) gif_index += 1 except tkinter.TclError: gif_index = 0 else: root.after(10, gif) #print(gif_index, end = " ") #if gif_index == 0: # print("\n") la = tkinter.Label(root, image = photo) en = tkinter.Entry() bu1 = tkinter.Button(root, text = "Roll", command = start) bu2 = tkinter.Button(root, text = "Stop", command = stop) la.pack() en.pack() bu1.pack() bu2.pack() root.mainloop()

良い質問の評価を上げる

以下のような質問は評価を上げましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

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

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

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

teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

  • プログラミングに関係のない質問
  • やってほしいことだけを記載した丸投げの質問
  • 問題・課題が含まれていない質問
  • 意図的に内容が抹消された質問
  • 過去に投稿した質問と同じ内容の質問
  • 広告と受け取られるような投稿

評価を下げると、トップページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

まだ回答がついていません

会員登録して回答してみよう

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

ただいまの回答率
87.20%

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

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

質問する

関連した質問

同じタグがついた質問を見る

OpenCV

OpenCV(オープンソースコンピュータービジョン)は、1999年にインテルが開発・公開したオープンソースのコンピュータビジョン向けのクロスプラットフォームライブラリです。

Python 3.x

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

Tkinter

Tkinterは、GUIツールキットである“Tk”をPythonから利用できるようにした標準ライブラリである。

Python

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