Уведомления

Группа в Telegram: @pythonsu

#1 Фев. 8, 2015 16:31:00

wegwgweg
Зарегистрирован: 2015-02-02
Сообщения: 12
Репутация: +  0  -
Профиль   Отправить e-mail  

Асинхроннация инициализация объектов

Есть gui приложение при старте которого, нужно проинициализировать несколько объектов (один из объектов выполняет файловые операции, другой запрашивает данные из сети), чтобы окно программы появлялось сразу, хочу выполнять инициализацию объектов асинхронно относительно основного потока программы, который выполняет рисование окна.
Так как эти объекты предполагается использовать на всем протяжении жизни программы, нужно как-то иметь к ним доступ, чтобы можно их было в дальнейшем передавать функциям как аргументы и т д

Подскажите пожалуйста как правильно организовать асинхронную инициализацию объектов и как в дальнейшим к ним можно получить доступ?

P.S использую pyqt.

Офлайн

#2 Фев. 9, 2015 08:16:36

Alen
Зарегистрирован: 2013-08-01
Сообщения: 373
Репутация: +  49  -
Профиль   Отправить e-mail  

Асинхроннация инициализация объектов

wegwgweg
Так как эти объекты предполагается использовать на всем протяжении жизни программы, нужно как-то иметь к ним доступ, чтобы можно их было в дальнейшем передавать функциям как аргументы и т д

А зачем вам для этого асинхронность?

wegwgweg
чтобы окно программы появлялось сразу, хочу выполнять инициализацию объектов асинхронно относительно основного потока программы, который выполняет рисование окна.

Для этого потоки есть, как в Python, так и в Qt.

Офлайн

#3 Фев. 9, 2015 13:09:13

wegwgweg
Зарегистрирован: 2015-02-02
Сообщения: 12
Репутация: +  0  -
Профиль   Отправить e-mail  

Асинхроннация инициализация объектов

Alen
Для этого потоки есть, как в Python, так и в Qt.
Я понимаю, у меня проблема в том как организовать саму логику программы. Как их лучше всего проинициализировать и вернуть обратно в программу, чтобы их можно было там использовать уже?

Офлайн

#4 Фев. 9, 2015 14:55:25

Alen
Зарегистрирован: 2013-08-01
Сообщения: 373
Репутация: +  49  -
Профиль   Отправить e-mail  

Асинхроннация инициализация объектов

wegwgweg
Я понимаю, у меня проблема в том как организовать саму логику программы. Как их лучше всего проинициализировать и вернуть обратно в программу, чтобы их можно было там использовать уже?

Ну это же стандартная проблема для PyQt. Берем любое действие, которое требует одновременное получение внешних данных и обновление интерфейса, рассмотрим обновление прогрессбара при получение данных (в данном случае эмуляция):

import time
from PyQt4 import QtCore, QtGui
 
class SleepProgress(QtCore.QThread):
    procDone = QtCore.pyqtSignal(bool)
    partDone = QtCore.pyqtSignal(int)
    def run(self):
        print ('proc started')
        for a in range(1, 1+35):
            self.partDone.emit(float(a)/35.0*100)
            print('sleep', a)
            time.sleep(0.2)
 
        self.procDone.emit(True)   
        print('proc ended')
 
class AddProgresWin(QtGui.QWidget):
    def __init__(self, parent=None):
        super(AddProgresWin, self).__init__(parent)
        self.thread = SleepProgress()
        self.nameLabel = QtGui.QLabel("0.0%")
        self.nameLine = QtGui.QLineEdit()
        self.progressbar = QtGui.QProgressBar()
        self.progressbar.setMinimum(1)
        self.progressbar.setMaximum(100)
        mainLayout = QtGui.QGridLayout()
        mainLayout.addWidget(self.progressbar, 0, 0)
        mainLayout.addWidget(self.nameLabel, 0, 1)
        self.setLayout(mainLayout)
        self.setWindowTitle("Processing")
        self.thread.partDone.connect(self.updatePBar)
        self.thread.procDone.connect(self.fin)
        self.thread.start()
 
    def updatePBar(self, val):
        self.progressbar.setValue(val)
        perct = "{0}%".format(val)
        self.nameLabel.setText(perct)
     
    def fin(self):
        sys.exit()
 
if __name__ == '__main__':
    import sys
    app = QtGui.QApplication(sys.path)
    pbarwin = AddProgresWin()
    pbarwin.show()
    sys.exit(app.exec_())          

Как видите “процесс генерации данных” идет в отдельном потоке и генерирует события, а “окошко” ловит эти события и обрабатывает.
В вашем случае будут 2 процесса генерации данных, только и всего.

Офлайн

#5 Фев. 9, 2015 22:33:50

doza_and
От:
Зарегистрирован: 2010-08-15
Сообщения: 4138
Репутация: +  253  -
Профиль   Отправить e-mail  

Асинхроннация инициализация объектов

Alen
В вашем случае будут 2 процесса генерации данных, только и всего
И еще возникнет дополнительное состояние программы когда она полужива. И во всех местах где используются эти данные понадобятся проверки состояния.



Офлайн

#6 Фев. 10, 2015 07:10:22

Alen
Зарегистрирован: 2013-08-01
Сообщения: 373
Репутация: +  49  -
Профиль   Отправить e-mail  

Асинхроннация инициализация объектов

doza_and
И еще возникнет дополнительное состояние программы когда она полужива.

Это как?

doza_and
И во всех местах где используются эти данные понадобятся проверки состояния

Во всех местах, это где? Задача, как я понял, состоит в том чтобы связать процессы получения данных и отображения этих данных в GUI. Т.е. место одно, обработчик на каждый event один.

Офлайн

#7 Фев. 10, 2015 09:17:42

doza_and
От:
Зарегистрирован: 2010-08-15
Сообщения: 4138
Репутация: +  253  -
Профиль   Отправить e-mail  

Асинхроннация инициализация объектов

Alen
связать процессы получения данных и отображения этих данных
ТС нигде не пишет как он их использует. Это ваша догадка.

Код программы после инициализации данных может опираться на контракт что эти данные существуют и валидны. Собственно выделение фазы инициализации для этого и нужно. Если инициализация асинхронная, то на это нельзя полагаться. Добавляется состояние программы с неинициализированными данными.
Пример:
Текстовый редактор. Вы начали выполнять асинхронно процедуру создания документа, поскольку он долго грузится с диска, когда пускаешь редактор указав имя файла в командной строке.
Что будет если во время загрузки вы нажмете Save? Ничего хорошего. Надо будет предусматривать засеривание save save_as load. Или накапливать эти команды в очереди команд в тоже самое время выполняя другие команды и это все в зависимости от состояния системы. Если асинхронности нет, то все эти ужимки не нужны.

Так можно делать, но хотелось чтобы ТС отдавал себе в этом отчет.



Отредактировано doza_and (Фев. 10, 2015 09:19:35)

Офлайн

#8 Фев. 10, 2015 10:40:47

Alen
Зарегистрирован: 2013-08-01
Сообщения: 373
Репутация: +  49  -
Профиль   Отправить e-mail  

Асинхроннация инициализация объектов

doza_and
ТС нигде не пишет как он их использует. Это ваша догадка.

Вот и я про то же, зачем переусложнять простые вещи.
Он нигде и не пишет, что всё не так и всё значительно сложнее, так что это тоже ваша догадка.

doza_and
Код программы после инициализации данных может опираться на контракт что эти данные существуют и валидны. Собственно выделение фазы инициализации для этого и нужно. Если инициализация асинхронная, то на это нельзя полагаться. Добавляется состояние программы с неинициализированными данными.

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

doza_and
Текстовый редактор. Вы начали выполнять асинхронно процедуру создания документа, поскольку он долго грузится с диска, когда пускаешь редактор указав имя файла в командной строке.
Что будет если во время загрузки вы нажмете Save? Ничего хорошего. Надо будет предусматривать засеривание save save_as load. Или накапливать эти команды в очереди команд в тоже самое время выполняя другие команды и это все в зависимости от состояния системы.

У каждого приложения своя архитектура. В данном случае человеку нужен мониторинг событий из 2 источников, для этого вполне достаточно обойтись стандартными средствами без велосипедов.

doza_and
Если асинхронности нет, то все эти ужимки не нужны.

Под асинхронностью я понимаю, в данном случае event loop, и он тут никак не поможет.

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version