2012-03-12 5 views
6

Я использую Qt + PyQt для разработки. Мое приложение очень-очень большое (20 МБ исходного кода). Он включает в себя множество различных меню и виджетов. Очень часто я изменяю только одну строку по методу в каком-то виджетах. Но для проверки изменений я отключу свое приложение, перезапусти его, перейдите в menu1 -> menu2 .... и только после этого шага я могу проверить изменения.Как отлаживать приложения PyQt без повторной перезагрузки?

Как я могу перезагрузить методы только для одного класса/виджета? Без закрытого/открытого приложения?

+2

Хороший вопрос. Я спросил что-то подобное, но гораздо более общее: http://stackoverflow.com/questions/9519384/editing-programs-while-they-are-running-how. – gdw2

+0

Некоторое время назад я попытался использовать модуль ['reimport'] (http://code.google.com/p/reimport/) с написанием некоторых обходных путей для PySide http://pastebin.com/VN0JPDfC (PyQt должен работа тоже). Это сработало, но иногда оно порождает непредсказуемые исключения. Я согласен с @jdi, что тестирование - лучший способ. – reclosedev

ответ

3

Мой общий ответ на это был бы неправ, его невозможно в прямом режиме. Основная проблема заключается в том, что при запуске приложения он загружает все в память, а ваши классы связаны с их методами и т. Д. Поэтому, чтобы обновить, значения, которые вы изменили в методе класса, вам придется уничтожьте этот класс (или виджет) и заново создайте его под обновленным источником (который также убьет детей).

Его недурен, но это будет выглядеть примерно так:

## main.py ## 

class MainWindow(QtGui.QMainWindow): 

    def __init__(self, *args, **kwargs): 
     super(MainWindow, self).__init__(*args, **kwargs) 
     self.resize(640,480) 
     self.central = widget.Widget() 
     self.setCentralWidget(self.central) 

     self.toolbar = QtGui.QToolBar() 
     self.toolbar.addAction("Reload Entire Widget", self._reloadWidget) 
     self.addToolBar(QtCore.Qt.TopToolBarArea, self.toolbar) 

    def _reloadWidget(self): 
     print "Reloading", widget 
     reload(widget) 
     self.central.deleteLater() 
     self.central = widget.Widget() 
     self.setCentralWidget(self.central) 

## widget.py ## 

class Widget(QtGui.QWidget): 

    def __init__(self, *args, **kwargs): 
     super(Widget, self).__init__(*args, **kwargs) 
     self.layout = QtGui.QVBoxLayout(self) 
     self.button = QtGui.QPushButton("Click") 
     self.layout.addWidget(self.button) 

     self.button.clicked.connect(self.testMethod) 

    def testMethod(self): 
     print "testmethod(): FOO" 

Опять же, я думаю, что этот подход является проблематичным и трудно иметь дело с, так как вы должны уничтожить и воссоздать виджет. Больше проблем возникает, когда части вашего приложения имеют сигналы, привязанные к слотам обновленного виджета. Затем вам также необходимо перезагрузить свои модули и повторно подключить их сигналы. Это становится большой ситуацией дерева зависимостей. Его достаточно сложно сделать со стандартным скриптом python, не говоря уже о том, чтобы попытаться сделать это с чем-то гораздо более устойчивым и динамичным, как и структура PyQt.

В принципе, не полагайтесь на эту способность. Вам лучше, может быть, setting up something with QTest, чтобы имитировать ваши повторяющиеся задачи.