Найти - Пользователи
Полная версия: Qt : Связывание модулей логики и гуи
Начало » GUI » Qt : Связывание модулей логики и гуи
1 2
topazz
Ткните носом как правильно должно выглядеть.

Есть файлы скриптов с логикой
Есть файл с гуем

logika.py - файл логики
    class Setting()
class Worker()
fun(set)
gui.py - главный гуи он же запускает приложение
    from logika import Setting, Worker

class windows()
setting = Setting()
worker = Worker ()
# Далее строим гуи, на основе показателей setting
# Делаем конекшены и обработчики и запускаем главное событие
worker.fun(setting)
Но тут встает вопрос как менять показатели гуи на основании того что делает worker, так как он не видит переменных главного окна.
Или же все что должно рисоваться в гуи должно работать в самом гуи классе?

Короче какое-то у меня не понимание, помогите.
pasaranax
Можно сделать склеивающий класс, который будет ловить сигналы от гуи и выполнять действия в логике.
п.с. вроде бы он называется Controller в той самой системе.
Митрич
ну да, тут либо Worker надо делать потомком QObject, либо “обернуть” его в QObject, который и будет с одной стороны передавать “работу” в класс или объект класса Worker (это зависит от реализации обертки: либо наследование, либо композиция), а с другой рассылать при этом сигналы в GUI.
topazz
Митрич
ну да, тут либо Worker надо делать потомком QObject, либо “обернуть” его в QObject, который и будет с одной стороны передавать “работу” в класс или объект класса Worker (это зависит от реализации обертки: либо наследование, либо композиция), а с другой рассылать при этом сигналы в GUI.
Не совсем понял как обернуть Worker?
Т.е. мы получается делаем экземпляр класса QObject, в котором делаем экземпляр Workera?

На данный момент я тупо запустил еще один тред, который дергает метод Workera получая от него все статусы и синхронит их с главным потоком, но это как-то убого.
Митрич
можно сделать примерно так: класс QWorker инициализируется объектом класса Worker, для всех методов интерфейса класса Worker (только если они открыты) пишутся соответствующие методы класса QWorker.
def qMethod(self,*args):
# здесь разослать предварительные сигналы (если надо)
self.worker.method(*args)
# здесь разослать сигналы о завершении (если надо)
другой вариант - наследовать QWorker от Worker и завести атрибут объекта signaller класса QObject, что особенно подходит, когда метод fun вызывает другие методы своего класса. тут новые методы должны быть примерно такими
def method(self,*args):
# здесь разослать предварительные сигналы (если надо)
self.signaller.preSignal.emit()
super().method(*args)
# здесь разослать сигналы о завершении (если надо)
self.signaller.postSignal.emit()
topazz
Вот еще ссыль для понимания, может кому пригодится
http://python.su/forum/viewtopic.php?id=1493
topazz
В продолжение темы.. не могу понять как правильно реализовать работу с потоками…

Есть 4 файла

Превый nastroiki.py - лежит класс всякого рода переменных, для гуи и логики.

class nastroi():
def __init__(self, parent):
self.parent = parent
self.maxcount = 10
self.curcount = 0
Второй kolbaser.py - клас логики где будет что-то долго и нужно обрабатываться, причем многопоточно. В данном случае просто апдейтит настройки и дергает функцию соседнего гуи класа

import time

class kolbaser():
def __init__(self, parent):
self.parent = parent

def dosomething(self):
self.parent.Setting.curcount = 0
while self.parent.Setting.curcount < self.parent.Setting.maxcount:
print self.parent.Setting.curcount
self.parent.Setting.curcount += 1
self.parent.Gui.upfdatelab()
# time.sleep(1)
Третий Gui.py - гуи. Дергает по клику функцию логики, запуская ее в потоке. Имеет функцию которую дергает логика.

import  threading
from PyQt4 import QtGui, QtCore

class Gui(QtGui.QMainWindow):
def __init__(self, parent):
QtGui.QMainWindow.__init__(self)
self.parent = parent
frame = QtGui.QFrame()
self.setCentralWidget(frame)
mainLayout = QtGui.QGridLayout()
frame.setLayout(mainLayout)

self.statLabel = QtGui.QLabel(self.trUtf8('Позиция: <strong>%s</strong>' % str(self.parent.Setting.curcount)))
self.startButton = QtGui.QPushButton(self.trUtf8('Пуск'))

mainLayout.addWidget(self.statLabel, 0 , 0, 1 , 1)
mainLayout.addWidget(self.startButton, 10 , 0, 2, 2)
self.buildcon()

def buildcon(self):
self.connect(self.startButton, QtCore.SIGNAL('clicked()'), self.Pusk )

def Pusk(self):
threading.Thread(target = self.parent.Action.dosomething, name = 'kolbaser').start()

def upfdatelab(self):
self.statLabel.setText(self.trUtf8('Позиция: <strong>%s</strong>' % str(self.parent.Setting.curcount)))
Четвертый main.py - все объединяет и является папой для всех, запускает гуй.

import sys
from PyQt4 import QtGui, QtCore

from nastroiki import nastroi
from kolbaser import kolbaser
from gui import Gui

class MainStarter():
def __init__(self):
self.Setting = nastroi(self)
self.Action = kolbaser(self)
self.Gui = Gui(self)


if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
main = MainStarter()
main.Gui.show()
sys.exit(app.exec_())
Вопрос.. если выставить в логике слипы и если maxcount маленькое число, то все вроде работает.
Но если сделать maxcount хотя бы в 10000, а слип убрать то все валится.

Как правильно организовать такую работу. Т.е. класс kolbaser будет что-то считать много поточно и писать изменения в класс настроек. Как апдейтить gui на основе новых данных..

Большое спасибо всем за терпение и помощь.
truporez
Оперируйте Queue
topazz
truporez
Оперируйте Queue
Что конкретно очередью делать надо?
Очередь будет в самой логике, там ее разбирать будет более 50 потоков.
Где очередь пихать в ГУИ, а главное зачем?

Затем чтобы писать в нее что надо запдейтить, но тогда потоки логики сделают такою очередь, что единственный поток гуи ее просто не будет успевать разгребать…

Короче вопрос остался.
truporez
Работать с гуей может только поток ее создавший.
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