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

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

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

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

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

Для этого потоки есть, как в Python, так и в Qt.
wegwgweg
Alen
Для этого потоки есть, как в Python, так и в Qt.
Я понимаю, у меня проблема в том как организовать саму логику программы. Как их лучше всего проинициализировать и вернуть обратно в программу, чтобы их можно было там использовать уже?
Alen
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 процесса генерации данных, только и всего.
doza_and
Alen
В вашем случае будут 2 процесса генерации данных, только и всего
И еще возникнет дополнительное состояние программы когда она полужива. И во всех местах где используются эти данные понадобятся проверки состояния.
Alen
doza_and
И еще возникнет дополнительное состояние программы когда она полужива.

Это как?

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

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

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

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

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

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

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

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

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

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

Под асинхронностью я понимаю, в данном случае event loop, и он тут никак не поможет.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB