停止tkinter mainloop扰乱matplotlib

时间:2016-04-19 14:47:51

标签: python python-2.7 matplotlib tkinter

嗨,我是一名学生,我是第一次与ktinker合作。我目前正在尝试创建一个遵循此顺序的程序:

  1. 在matplotlib中打开地图
  2. 调用弹出窗口供用户输入信息
  3. 当用户点击地图网格时的坐标和用户 信息存储在字典中
  4. matplotlib在位置上生成绘图点
  5. 麻烦的是,当我调用我在tkinter中编写的弹出窗口时,调用mainloop()函数会破坏matplotlib窗口,并且在地图窗口关闭之前它不会生成绘图点。

    摆脱mainloop修复它但后来意味着我无法从弹出窗口中获取数据。 任何人都知道如何阻止一个人干扰另一个人?我必须将它们保存在单独的类中,因为我的意思是在我的代码中演示模块化。 这是主要代码

        import matplotlib.pyplot as plt
    import matplotlib.image as mpimg
    import numpy as np
    import popup1 as ap
    
    __author__ = "k1221169"
    __date__ = "$15-Nov-2015 11:29:21$"
    
    
    markerList = []
    xplots = []
    yplots = []
    desc = ''
    title = ''
    fig = plt.figure()
    ax = fig.add_subplot(111)
    ax.plot(np.random.rand(10))
    img = mpimg.imread('overland map 1.png')
    imgplot = plt.imshow(img)
    plt.ylim(ymax=1)
    plt.xlim(xmin=1)
    
    
    def mrkApnd(a,b):
        a.update(b)
        print a
        markerList.append(a)
    
    def onclick(event):
    
        if spacecheck(event.xdata, event.ydata):
            #print markerList[0]['x']
            idx = np.abs(xplots - event.xdata).argmin()
            print xplots[idx]
    
            for i in markerList:
                if xplots[idx] == i['x'] :
                    print i
                    #c = i
                    ap.useroutput(i)
        else:
            input1 = ap.userinput()
            input2 = {'x':event.xdata, 'y':event.ydata}
            input1['title'] = title
            input1['desc'] = desc
            mrkApnd(input1,input2)
    
            drawMarks()
            print input1
    
        return markerList
    cid = fig.canvas.mpl_connect('button_press_event', onclick)
    
    def drawMarks():
        plt.ion()
        for i in markerList:
            xplots.append(i['x'])
            yplots.append(i['y'])
            plt.plot(i['x'], i['y'], i['type'])
    
    
    
    
    
    def spacecheck(x,y):
        a = bool
        if np.isclose(xplots, x, atol=50.0).any() and np.isclose(yplots, y, atol=50.00).any():
            a=True
            print 'yes'
            return a
    plt.draw()
    plt.show()
    

    这是从另一个文件调用的弹出代码

    from Tkinter import *
    
    class popup1():
        def __init__(self):
    
            pass
    
    def userinput():
    
    
        pop = Toplevel()
    
    
        pop.title("marker")
        pop.geometry("300x500+200+200")
    
        #string for title
    
        frame = Frame(pop)
        entry = Entry(frame)
        entry.pack(side = TOP)
        frame.pack( padx =20, pady =20)
    
    
    
        #radius button for visibility
        frame2 = Frame(pop)
        selection = StringVar()
        radio_1 = Radiobutton(frame2, text = 'Character', variable = selection, value = 'ob')
        radio_2 = Radiobutton(frame2, text = 'Item', variable = selection, value = 'or')
        radio_3 = Radiobutton(frame2, text='Event',  variable = selection, value = 'oy')
    
        radio_1.select()
        radio_1.pack(side = LEFT)
        radio_2.pack(side = LEFT)
        radio_3.pack(side = LEFT)
        frame2.pack(padx =30, pady =30)
        #radius button for marker type
        frame3 = Frame(pop)
        visible = bool
        check_1 = Checkbutton(frame3, text = 'GM Only', variable = visible, onvalue= True, offvalue= False)
    
        check_1.pack(side = LEFT)
        frame3.pack(padx =30, pady =30)
        #string for user input
        frame4 = Frame(pop)
        entry4 = Entry(frame4)
        entry4.pack(side = LEFT)
        frame4.pack( padx =20, pady =20)
    
    
    
        def infoPass():
            #info1 = {'title': entry.get(), 'type': selection.get(), 'vis': visible, 'Desc': entry4.get()}
            #info.update(info1)
            #print info
    
            pop.destroy()
    
        #buttons
        label = Label(pop, text="", height=0, width=100)
        label.pack()
        b = Button(pop, text="Cancel", width=20, command= pop.destroy )
        b.pack(side='bottom',padx=5,pady=5)
        b2 = Button(pop, text="Save", width=20, command= infoPass  )
        b2.pack(side='bottom',padx=5,pady=5)
        info = {'title': entry.get(), 'type': selection.get(), 'vis': visible, 'desc': entry4.get()}
        pop.mainloop()
        return info
    

1 个答案:

答案 0 :(得分:0)

如果我正确地解答了你的问题,那就试着添加你自己的循环。

  1. 删除pop.mainloop()

  2. 使代码成为更清洁代码的类

  3. 
        class userinput:
            def __init__(self):
                #open your window here and style it etc. and:
                self.data_sent = False
            def infopass(self):
                self.data_sent = True
                #your infopass code here and
    
    1. init
    2. 的末尾创建自己的循环
      
              def __init__(self):
                  #...
                  while self.data_sent == False:
                      root.update()
      
          while data_sent == False:
              pop.update()
      
      
      1. 通过

        调用您的弹出窗口

        mypopup = userinput()

      2. 祝你好运;)