-1

GUIでtkinterを使用してimshowでマトリックスを描画したいと思います。問題は、さらに更新した後、GUI がクラッシュすることです。私はウェブ上で答えを見つけることができません。助けていただけませんか?

コード:

from numpy import *
from Tkinter import *
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
from matplotlib.figure import Figure

root = Tk()
f1 = Figure()

canvas = FigureCanvasTkAgg(f1, master=root)
canvas.show()
canvas.get_tk_widget().pack(fill="x")
a = f1.add_subplot(111)
a.get_axes().set_frame_on(True)
ini = [[i] * 100 for i in range(100)]
cax = a.matshow(ini)

while True:
    mat = random.randint(0, 2**16-1, (1000, 1000))
    cax.set_data(mat)
    canvas.draw()

root.mainloop()

あなたの提案fhdrsdgに感謝しますが、この方法を行うと、再描画の実行中にウィンドウがフリーズします。これは、特にこれまでにやるべきことがたくさんある場合に退屈です。

これが私のコードです:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from Tkinter import Button, Label, Text, Checkbutton, Radiobutton, Frame, Tk, Entry, INSERT, StringVar, IntVar, Toplevel, END
from ttk import Notebook, Combobox
from numpy import arange, zeros, array, uint16, empty, divide, random, ravel
import matplotlib
matplotlib.use('TkAgg')
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
from matplotlib.figure import Figure
from matplotlib import cm
from matplotlib.image import AxesImage
import time
from threading import Thread
import os



class Image_direct(Thread):

    def __init__(self):
        Thread.__init__(self)
        self.encore = True

    def run(self):
        """This loop can be long ~10s"""
        while self.encore:
            time.sleep(1)
            app.cax.set_extent((0, 1023, 1023, 0))
            mat = random.randint(0, 2**16-1, (1024, 1024)).astype("uint16")
            app.update_camera(mat)

    def stop(self):
        self.encore = False


class Deu(Frame):

    def __init__(self, master):
        Frame.__init__(self, master)
        self.creer_applets()

    def creer_applets(self):
        self.fen4 = Frame(fen)
        self.fen4.pack(side="bottom", fill="both")
        self.fen1 = Frame(fen, width=200)
        self.fen1.pack(side="left", fill="both", expand=False)
        self.note = Notebook(fen, width=1)
        self.tab_mat = Frame(self.note)
        self.note.add(self.tab_mat, text = "Caméra", compound="top")
        self.note.pack(side="left", fill="both", expand=True)
        self.fen3 = Frame(fen, width=250)
        self.fen3.pack(side="left", fill="both", expand=False)

        Button(self.fen4, text="Quit", command=self.aurevoir).pack(fill="x", side="top")

        self.interp = StringVar()
        self.interp.set("none")
        liste_interp = ["none", "nearest", "bilinear", "bicubic", "spline16", "spline36", "hanning", "hamming", "hermite", "kaiser", "quadric", "catrom", "gaussian", "bessel", "mitchell", "sinc", "lanczos"]
        self.choix_interp = Combobox(self.tab_mat, textvariable=self.interp, state="readonly", width=10)
        self.choix_interp['values'] = liste_interp
        self.cmap = StringVar()
        self.cmap.set("jet")
        palettes = sorted(m for m in cm.datad if not m.endswith("_r"))
        self.choix_palette = Combobox(self.tab_mat, textvariable=self.cmap, state="readonly", width=10)
        self.choix_palette['values'] = palettes
        self.bouton_palette = Button(self.tab_mat, text="Changer la palette", command=self.changer_cmap)

        self.f1 = Figure()
        self.canvas1 = FigureCanvasTkAgg(self.f1, master=self.tab_mat)
        self.canvas1.show()
        self.canvas1.get_tk_widget().pack(fill="both", expand=1)
        NavigationToolbar2TkAgg(self.canvas1, self.tab_mat)
        self.a = self.f1.add_subplot(111)
        self.bg = self.canvas1.copy_from_bbox(self.a.bbox)
        self.a.get_axes().set_frame_on(True)
        ini = random.randint(0, 2**16-1, (1024, 1024))
        self.cax = self.a.matshow(ini, cmap=self.cmap.get(), interpolation=self.interp.get(), picker=True, alpha=1.0)
        self.a.format_coord = lambda x, y: 'x=%d, y=%d, z=%d' % (x, y, ini[round(y), round(x)])
        self.cbar = self.f1.colorbar(self.cax)
        self.cbar.set_label("coups")
        self.bouton_palette.pack(side="left")
        self.choix_interp.pack(side="left")
        self.choix_palette.pack(side="left")

        Button(self.tab_mat, text=">", command=lambda: self.changer_cbar(1)).pack(side="right")
        self.cbar_auto = IntVar()
        self.chb3 = Checkbutton(self.tab_mat, text="Auto?", variable=self.cbar_auto, onvalue=1, offvalue=0, indicatoron=0, command=lambda: self.changer_cbar(0))
        self.chb3.select()
        self.chb3.pack(side="right")
        Button(self.tab_mat, text="<", command=lambda: self.changer_cbar(-1)).pack(side="right")

        self.bouton_direct_on = Button(self.fen3, width=20, text="Démarrer le direct", command=self.image_direct_on)
        self.bouton_direct_on.place(x=0, y=400)
        self.bouton_direct_off = Button(self.fen3, width=20, text="Arrêter le direct", command=self.image_direct_off)
        self.bouton_direct_off.config(state="disabled")
        self.bouton_direct_off.place(x=0, y=430)

    def changer_cbar(self, sens):
        if sens == -1:
            self.cbar.set_clim(vmin=self.cax.get_array().min(), vmax=0.9*self.cbar.get_clim()[1])
        elif sens == 0 and self.cbar_auto.get():
            self.cbar.set_clim(vmin=self.cax.get_array().min(), vmax=self.cax.get_array().max())
        elif sens == 1:
            self.cbar.set_clim(vmin=self.cax.get_array().min(), vmax=2*self.cbar.get_clim()[1])
        self.cax.set_clim(self.cbar.get_clim())
        self.canvas1.restore_region(self.bg)
        self.a.draw_artist(self.f1)
        self.canvas1.blit(self.f1.bbox)

    def changer_cmap(self):
        self.cax.set_cmap(self.cmap.get())
        self.cax.set_interpolation(self.interp.get())
        self.canvas1.draw()

    def update_camera(self, mat):
        xmin = min([int(i) for i in app.a.get_xlim()])
        xmax = max([int(i) for i in app.a.get_xlim()])
        ymin = min([int(i) for i in app.a.get_ylim()])
        ymax = max([int(i) for i in app.a.get_ylim()])
        self.a.format_coord = lambda x, y: 'x=%d, y=%d, z=%d' % (x, y, mat[round(y), round(x)])
        self.cax.set_data(mat)
        self.changer_cbar(0)

    def image_direct_on(self):
        self.bouton_direct_off.config(state="normal")
        self.bouton_direct_on.config(state="disabled")
        self.dire = Image_direct()
        self.dire.setDaemon(True)
        self.dire.start()

    def image_direct_off(self):
        self.bouton_direct_off.config(state="disabled")
        self.bouton_direct_on.config(state="normal")
        self.dire.stop()
        del self.dire

    def aurevoir(self):
        try:
            self.dire.isAlive()
        except:
            pass
        else:
            self.dire.stop()
        fen.quit()
        fen.destroy()


if __name__ == '__main__':
    fen = Tk()
    fen.geometry("1300x750")
    app = Deu(fen)
    fen.mainloop()

奇妙なのは、次のことです。

  • カーソルが画像上にあるときにクラッシュが発生する

  • Linux では、クラッシュはありません。

カーソルが画像の上にあるとき、または画像をズーム/ズーム解除すると、数秒または数分で発生する可能性があります。すると、ウィンドウが白くなり、「pythonw.exe が応答していません」というメッセージとともにポップアップが表示されます。アイドルは何も言わない。私は完全な霧の中にいます:/

4

1 に答える 1