Как я могу открыть две разные фигуры пилаба из одной и той же кнопки из графического интерфейса wxpython? - PullRequest
2 голосов
/ 22 марта 2012

Я новичок в python, и у меня есть серьезная проблема, которую я не могу преодолеть.Я создал графический интерфейс, используя wxpython, который имеет два текстовых поля и кнопку.Когда эта кнопка нажата, я вызываю функцию, которая вызывает другую функцию, которая создает круговую диаграмму в соответствии с вводом в текстовых полях.Проблема заключается в том, что если пользователь не закрывает фигуру, вводит новые значения в текстовые поля и снова нажимает кнопку, программа вылетает вместо отображения второй фигуры.Я пытался создать разные темы при нажатии кнопки, результат тот же.

Более конкретно:

это функции, которые вызываются при нажатии кнопки:

def statistics_button (self, event):

   t=threading.Thread(target=self.m_button21OnButtonClick,args=(event,))
    t.start()
    print t    

def m_button21OnButtonClick( self, event ):

    '''some code here'''


    fig=statistics.mmr_dist(mmr1,mmr2) 

    show()

сначала вызывается кнопка statistics_, а затем вызывается m_button21OnButtonClick.функция statistics.mmr_dist выглядит следующим образом:

'''some code'''
fig=pylab.figure(tit,figsize=(8,8),frameon=False)

ax=pylab.axes([0.1, 0.1, 0.8, 0.8])
pita=pylab.pie(db.values(), labels=tuple(db.keys()), autopct='%1.1f%%', shadow=True)
ti="%s-%s\n Maximum Distance = %s m\n Minimum Distance = %s m" % (ddf1.label,ddf2.label,maxdist,mindist)
title(ti, bbox={'facecolor':'0.8', 'pad':5}) 


'''some code'''

return fig

До сих пор я понял, что команда show () блокирует завершение функции m_button21OnButtonClick, поэтому ее нельзя вызывать снова при нажатии кнопки, если на рисункезакрыто.Но по этой причине я реализовал разные темы.Хотя это не похоже на работу.

Ответы [ 3 ]

1 голос
/ 22 марта 2012

См. на этой странице для получения советов по настройке pylab для работы с wxPython - что вы, вероятно, не должны на самом деле пытаться (см. Следующий параграф). Проблема в том, что pylab использует Tkinter, который несовместим с работающей копией wxPython.

В конечном счете, вы должны просто встроить свои графики в wxPython . Это работает очень хорошо и в любом случае лучше для пользователя.

0 голосов
/ 22 марта 2012

Если вы хотите создать круговые диаграммы или другие типы графиков в wxPython, вам следует использовать PyPlot (входит в wx) или matplotlib, которые могут быть встроены в wxPython. В демоверсии wxPython есть пример PyPlot. Матплот см. Здесь здесь или здесь .

0 голосов
/ 22 марта 2012

Попробуйте ввести команду pylab.ion() после импорта pylab, и посмотрите, позволяет ли это показать несколько графиков. Это всегда был мой подход, когда мне приходилось многократно отображать графики обновления, не закрывая окно.

Обратите внимание, что вам нужно будет создавать новые объекты фигур и осей для каждого отдельного окна графика, в противном случае графики будут перезаписывать старые графики.

Например, следующий код работает для меня, чтобы создать два окна с разными графиками:

 import pylab
 pylab.ion()

 fig1 = pylab.figure()
 fig1.add_subplot(111).plot([1,2],[3,4])
 pylab.draw()

 fig2 = pylab.figure()
 fig2.add_subplot(111).plot([5,6],[10,9])
 pylab.draw()

Добавлена ​​

Учитывая ваши последующие комментарии, вот новый скрипт, который использует show(), но который отображает разные графики каждый раз, когда вызывается pylab.draw(), и который оставляет окна графиков неопределенными. Он использует простую логику ввода, чтобы решить, когда закрывать фигуры (потому что использование show() означает, что pylab не будет обрабатывать щелчки на кнопке windows x), но это должно быть просто добавить в графический интерфейс пользователя как другую кнопку или как текстовое поле .

import numpy as np
import pylab
pylab.ion()

def get_fig(fig_num, some_data, some_labels):

    fig = pylab.figure(fig_num,figsize=(8,8),frameon=False)
    ax = fig.add_subplot(111)
    ax.set_ylim([0.1,0.8]); ax.set_xlim([0.1, 0.8]);
    ax.set_title("Quarterly Stapler Thefts")
    ax.pie(some_data, labels=some_labels, autopct='%1.1f%%', shadow=True);
    return fig

my_labels = ("You", "Me", "Some guy", "Bob")

# To ensure first plot is always made.
do_plot = 1; num_plots = 0;

while do_plot:
    num_plots = num_plots + 1;
    data = np.random.rand(1,4).tolist()[0]

    fig = get_fig(num_plots,data,my_labels)
    fig.canvas.draw()
    pylab.draw()

    print "Close any of the previous plots? If yes, enter its number, otherwise enter 0..."
    close_plot = raw_input()

    if int(close_plot) > 0:
        pylab.close(int(close_plot))

    print "Create another random plot? 1 for yes; 0 for no."
    do_plot = raw_input();

    # Don't allow plots to go over 10.
    if num_plots > 10:
        do_plot = 0

pylab.show()
...