Уведомления

Группа в Telegram: @pythonsu
  • Начало
  • » GUI
  • » QSpinBox Qt5 передача значения в питон [RSS Feed]

#1 Июль 16, 2018 16:52:29

PEHDOM
Зарегистрирован: 2016-11-28
Сообщения: 2196
Репутация: +  294  -
Профиль   Отправить e-mail  

QSpinBox Qt5 передача значения в питон

Venus
по приведённым вам примерам по ссылке думаю этот нужен(незнаю как его впихнуть в деф старт)
возможно но не факт, поскольку ХЗ что делает твой внешний модуль, это для нас тайна за семью печатями, то возможны проблемы изза GIL https://ru.wikipedia.org/wiki/Global_Interpreter_Lock
НО в принципе это решает multiprocessing благо его методы о многом повторяют threading, и смена не соствит труда.
Venus
и совсем непонятно что это(откуда переменные взялись)
как откуда это просто пример, создаються два потока “с” и “b”. “b” выполняеться “демоном” тоесть даже после завершения основного скрипта он продолжит работу. А “с” мы ждем когда он закончит свою работу и только тогда продолжаем выполнение основного потока.
Не обязательно наследовать от класса Thread, процесс\поток можно создать из процедуры\функкции

 #
import sys
import time
import threading
try:
    from PyQt4 import QtGui
except:
    from PyQt5 import QtWidgets as QtGui
def ext_script(r, t, stop_event):
    # типа кагбэ внешний скрипт
    # надеюсь у тебя есь механиз выхода из бконечного цикла, иначе нужно его предусмотреть.
    #
    # Параметры:
    # r, t - просто какието параметры передаваемые в нпоток
    # stop_event - специальный ивент типа threading.Event для отсановки бесконечного цикла
    while not stop_event.is_set(): # выполнять бесконечный цикл пока stop_event = False
        # эмуляция какойто работы
        print('script run with params r={}, t={}'.format(r, t))
        time.sleep(1)
class MainWindow(QtGui.QWidget):
    def __init__(self, parent = None):
        super().__init__(parent = parent)
        self.seconary_thread = None # Атрибут класса для второго потока
        self.thread_stop_event = threading.Event() # сигнал для отсновки второго потока
        self.layout = QtGui.QGridLayout(self)
        # r
        self.r_label = QtGui.QLabel(self, text = 'r:')
        self.r = QtGui.QSpinBox(self) # Создаем спинбокс
        self.r.setObjectName('r') # Устанавлваем имя виджета, чтобы понимать кто отправитель события
        self.r.setRange(1, 10)
        self.r.setSingleStep(1)
        self.layout.addWidget(self.r_label, 0, 0)
        self.layout.addWidget(self.r, 0, 1)
        # t
        self.t_label = QtGui.QLabel(self, text = 't:')
        self.t = QtGui.QSpinBox(self) # Создаем спинбокс
        self.t.setObjectName('t') # Устанавлваем имя виджета, чтобы понимать кто отправитель события
        self.t.setRange(1, 10)
        self.t.setSingleStep(1)
        self.layout.addWidget(self.t_label, 1, 0)
        self.layout.addWidget(self.t, 1, 1)
        self.t.installEventFilter(self)
        # Кнопка старт
        self.start_btn = QtGui.QPushButton(self, text = 'START')
        self.layout.addWidget(self.start_btn, 2, 0)
        self.start_btn.clicked.connect(self.start_act)
        # Кнопка стоп
        self.stop_btn = QtGui.QPushButton(self, text = 'STOP!')
        self.layout.addWidget(self.stop_btn, 2, 1)
        self.stop_btn.clicked.connect(self.stop_act)
        self.show()
    def start_act(self):
        if not self.seconary_thread or not self.seconary_thread.is_alive(): #  Если поток еще не существует или он не живой
            r = self.get_r() # получаем r
            t = self.get_t() # получаем t
            self.thread_stop_event.clear() # Устанавливаем сигнал в False
            self.seconary_thread = threading.Thread(target= ext_script, args = (r, t, self.thread_stop_event))
            # Создаем поток из функции target= ext_script
            #  м передаем ей аргументы args = (r, t, self.thread_stop_event)
            self.seconary_thread.start() # запускаем поток
        else: # если поток уже существует , еще один нам не нужен
            print('one secondary thread alredy running.')
    def stop_act(self):
        if self.seconary_thread and self.seconary_thread.is_alive(): # Если поток "живой"
            self.thread_stop_event.set()    # Устанавливаем флаг в Trye
        else:
            print('thread not running.')
    def get_r(self):
        # возвращает r
        return self.r.value()
    def get_t(self):
        # возвращает t
        return self.t.value()
if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)
    mw = MainWindow()
    app.exec_()



==============================
Помещайте код в теги:
[code python][/code]
Бериегите свое и чужое время.

Отредактировано PEHDOM (Июль 16, 2018 16:59:50)

Офлайн

#2 Июль 16, 2018 18:29:30

Venus
Зарегистрирован: 2017-05-19
Сообщения: 55
Репутация: +  0  -
Профиль   Отправить e-mail  

QSpinBox Qt5 передача значения в питон

PEHDOM
не сочти за наглость(голова взрывается от информации прочтённой о мультипроцессорности и тому подобное), я так понимаю мне функцию надо в поток засунуть или окно виджета!?!наверное функцию а именно деф start, не могли бы вы конкретно на моём примере?примеры в интернете на с++ и для какихто массивов запросов к серверу и прочее как засунуть деф в поток (либ плохо смотрел либо както сложно для меня объясняют) я не понял ((
 from PyQt5 import QtWidgets
from PyQt5 import QtWidgets as QtGui
from samplestrorint import *
import sys
import strorint1
def log_uncaught_exceptions(ex_cls, ex, tb):
    text = '{}: {}:\n'.format(ex_cls.__name__, ex)
    import traceback
    text += ''.join(traceback.format_tb(tb))
    print(text)
    QMessageBox.critical(None, 'Error', text)
    quit()
    
sys.excepthook = log_uncaught_exceptions
class MainWindow(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        QtWidgets.QWidget.__init__(self, parent)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.statusBar().showMessage('Stop')
        self.ui.pushButton.clicked.connect(self.Start)
        self.ui.pushButton_2.clicked.connect(self.Stop)
        self.ui.pushButton.clicked.connect(lambda: self.statusBar().showMessage('запущен'))
        self.ui.pushButton_2.clicked.connect(lambda: self.statusBar().showMessage('остановлен'))
                
    def Start(self):
        
        r = self.ui.textEdit_9.toPlainText()
        strorint1.r = int(r)
        
    def Stop(self):
        
        strorint1.stop()
        
if __name__=="__main__":
    app = QtWidgets.QApplication(sys.argv)
    myapp = MainWindow()
    myapp.show()
    sys.exit(app.exec_())
    

Офлайн

#3 Июль 16, 2018 18:45:17

Venus
Зарегистрирован: 2017-05-19
Сообщения: 55
Репутация: +  0  -
Профиль   Отправить e-mail  

QSpinBox Qt5 передача значения в питон

почему просто не могу добавить это threading.Thread(target=start).start() в

 def Start(self):
        threading.Thread(target=start).start()
        r = self.ui.textEdit_9.toPlainText()
        strorint1.r = int(r)

Офлайн

#4 Июль 17, 2018 09:22:03

Venus
Зарегистрирован: 2017-05-19
Сообщения: 55
Репутация: +  0  -
Профиль   Отправить e-mail  

QSpinBox Qt5 передача значения в питон

Добавил t1 = threading.Thread(target=Start) t1.start() пишет NameError: name ‘Start’ is not defined

 from PyQt5 import QtWidgets
from PyQt5 import QtWidgets as QtGui
from samplestrorint import *
import sys
import strorint1
def log_uncaught_exceptions(ex_cls, ex, tb):
    text = '{}: {}:\n'.format(ex_cls.__name__, ex)
    import traceback
    text += ''.join(traceback.format_tb(tb))
    print(text)
    QMessageBox.critical(None, 'Error', text)
    quit()
    
sys.excepthook = log_uncaught_exceptions
class MainWindow(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        QtWidgets.QWidget.__init__(self, parent)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.statusBar().showMessage('Stop')
        self.ui.pushButton.clicked.connect(self.Start)
        self.ui.pushButton_2.clicked.connect(self.Stop)
        self.ui.pushButton.clicked.connect(lambda: self.statusBar().showMessage('запущен'))
        self.ui.pushButton_2.clicked.connect(lambda: self.statusBar().showMessage('остановлен'))
                
    def Start(self):
        t1 = threading.Thread(target=Start) <-или здесь написать деф внешнего вызываемого модуля?
        t1.start()
        r = self.ui.textEdit_9.toPlainText()
        strorint1.r = int(r)
        
    def Stop(self):
        
        strorint1.stop()
        
if __name__=="__main__":
    app = QtWidgets.QApplication(sys.argv)
    myapp = MainWindow()
    myapp.show()
    sys.exit(app.exec_())
    

Отредактировано Venus (Июль 17, 2018 09:54:29)

Офлайн

#5 Июль 17, 2018 12:23:54

PEHDOM
Зарегистрирован: 2016-11-28
Сообщения: 2196
Репутация: +  294  -
Профиль   Отправить e-mail  

QSpinBox Qt5 передача значения в питон

Venus
Добавил t1 = threading.Thread(target=Start) t1.start() пишет NameError: name ‘Start’ is not defined
Ты пытаешься создать поток из метода внутри самого метода, и хорошо что не получилось, иначе оно бы до бесконечности спаунило новые потоки.

Venus
from PyQt5 import QtWidgets as QtGui
так вообще делать не нужно, так как в PyQt5 есть модуль QtGui, это было решение исключительно для частного случая, когда у меня PyQt4 а у тебя PyQt5 и не используеться PyQt5.QtGui.

Venus
я так понимаю мне функцию надо в поток засунуть или окно виджета
функцию наверно, хотя не зная что делает функция тяжело однозначно ответить. Но точно не окно виджета, так PyQt событийно ориентированая среда.

Venus
не могли бы вы конкретно на моём примере?
могу но как только смогу увидеть рабочий пример, твой код пока ни рабочий ни пример. Так как состоит по большей части из непонятной ерунды. Я не понимаю что делает Start и накой ляд ее засовывать в поток. что делает strorint1? какие параметры оно принимает? где и как ты его собираешься вызывать? Что должно происходить когда меняется значение в спинбоксе, они должны передаваться в уже запущенный поток, или поток должен продолжать работать с прежними значениями пока его не остатновят и не запустят снова.

Пока у нас получается разговор слепого с глухим, я тебе показываю одно ты игноришь и пытаешься чтото химичить на своем примере, который по моим понятиям в приницпе работать не может.
ТАк что давай так , ты выкидываешь из своего кода все лишнее, оставляешь только, например, два(или сколько нужно) спинбокса(текстЕдита), и две кнопки стоп и старт. чтобы его можно было запустить и увидеть результат не только на твоем компьютере. Ты выкидываешь из “внешнего вызываемого модуля” все лишнее, заменяешь всю работу принтом по типу.
 print('script run r={}, t={}'.format(r, t)) # Или какие другие переменные
time.sleep(1)
чтобы, опять же его можно было запустить и увидеть что оно работает.
Выкладываешь это сюда, чтобы его можно было запустить и пишешь: я хочу чтобы когда я нажимаю кнопку старт запускалась такаято процедура такогото модуля в отдельном потоке, когда меняеться значение спинбокса параметр внутри скрипта (не)менялся на ходу и тд. тода можно буде чтото конкретное сказать.






==============================
Помещайте код в теги:
[code python][/code]
Бериегите свое и чужое время.

Офлайн

#6 Июль 17, 2018 12:40:47

Venus
Зарегистрирован: 2017-05-19
Сообщения: 55
Репутация: +  0  -
Профиль   Отправить e-mail  

QSpinBox Qt5 передача значения в питон

PEHDOM
вот main
 from PyQt5 import QtWidgets
from samplestrorint import *
import sys
import strorint1
def log_uncaught_exceptions(ex_cls, ex, tb):
    text = '{}: {}:\n'.format(ex_cls.__name__, ex)
    import traceback
    text += ''.join(traceback.format_tb(tb))
    print(text)
    QMessageBox.critical(None, 'Error', text)
    quit()
    
sys.excepthook = log_uncaught_exceptions
class MainWindow(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        QtWidgets.QWidget.__init__(self, parent)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.statusBar().showMessage('Stop')
        self.ui.pushButton.clicked.connect(self.Start)
        self.ui.pushButton_2.clicked.connect(self.Stop)
        self.ui.pushButton.clicked.connect(lambda: self.statusBar().showMessage('запущен'))
        self.ui.pushButton_2.clicked.connect(lambda: self.statusBar().showMessage('остановлен'))
                
    def Start(self):
        
        r = self.ui.textEdit.toPlainText()
        strorint1.r = int(r)
        strorint1.strorint()
    def Stop(self):
        n = self.ui.textEdit_2.toPlainText()
        #strorint1.n = int(r)
        strorint1.stop()
        
if __name__=="__main__":
    app = QtWidgets.QApplication(sys.argv)
    myapp = MainWindow()
    myapp.show()
    sys.exit(app.exec_())
    
вот внешний модуль
 # -*- coding: utf-8 -*-
import time
r = ('')
n = ()
def strorint():
    time.sleep(r)
    print(r, type(r))
    strorint()
def stop():
    print("Перезапуск",r,type(r))
    time.sleep(r)
    #strorint()
старт нажимаешь и зависает, хотя скрипт работает

Офлайн

#7 Июль 17, 2018 12:42:12

Venus
Зарегистрирован: 2017-05-19
Сообщения: 55
Репутация: +  0  -
Профиль   Отправить e-mail  

QSpinBox Qt5 передача значения в питон

вот форма

 # -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'samplestrorint.ui'
#
# Created by: PyQt5 UI code generator 5.10.1
#
# WARNING! All changes made in this file will be lost!
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(342, 236)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.label = QtWidgets.QLabel(self.centralwidget)
        self.label.setGeometry(QtCore.QRect(10, 20, 111, 31))
        self.label.setObjectName("label")
        self.label_2 = QtWidgets.QLabel(self.centralwidget)
        self.label_2.setGeometry(QtCore.QRect(10, 80, 141, 21))
        self.label_2.setObjectName("label_2")
        self.pushButton = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton.setGeometry(QtCore.QRect(10, 150, 75, 23))
        self.pushButton.setObjectName("pushButton")
        self.pushButton_2 = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_2.setGeometry(QtCore.QRect(200, 150, 75, 23))
        self.pushButton_2.setObjectName("pushButton_2")
        self.textEdit = QtWidgets.QTextEdit(self.centralwidget)
        self.textEdit.setGeometry(QtCore.QRect(120, 10, 111, 41))
        self.textEdit.setObjectName("textEdit")
        self.textEdit_2 = QtWidgets.QTextEdit(self.centralwidget)
        self.textEdit_2.setGeometry(QtCore.QRect(140, 70, 104, 41))
        self.textEdit_2.setObjectName("textEdit_2")
        MainWindow.setCentralWidget(self.centralwidget)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)
        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)
    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.label.setText(_translate("MainWindow", "Время перезапуска"))
        self.label_2.setText(_translate("MainWindow", "Ввести букву или цифру"))
        self.pushButton.setText(_translate("MainWindow", "Start"))
        self.pushButton_2.setText(_translate("MainWindow", "Stop"))

Офлайн

#8 Июль 17, 2018 15:21:27

Venus
Зарегистрирован: 2017-05-19
Сообщения: 55
Репутация: +  0  -
Профиль   Отправить e-mail  

QSpinBox Qt5 передача значения в питон

добавил в код @thread выдало TypeError: Start() takes 1 positional argument but 2 were given, откуда второй вылез

 from PyQt5 import QtWidgets
import threading
from samplestrorint import *
import sys
import strorint1
def log_uncaught_exceptions(ex_cls, ex, tb):
    text = '{}: {}:\n'.format(ex_cls.__name__, ex)
    import traceback
    text += ''.join(traceback.format_tb(tb))
    print(text)
    QMessageBox.critical(None, 'Error', text)
    quit()
    
sys.excepthook = log_uncaught_exceptions
def thread(fn):
    
    def execute(*args, **kwargs):
        threading.Thread(target=fn, args=args, kwargs=kwargs).start()
    return execute
class MainWindow(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        QtWidgets.QWidget.__init__(self, parent)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.statusBar().showMessage('Stop')
        self.ui.pushButton.clicked.connect(self.Start)
        self.ui.pushButton_2.clicked.connect(self.Stop)
        self.ui.pushButton.clicked.connect(lambda: self.statusBar().showMessage('запущен'))
        self.ui.pushButton_2.clicked.connect(lambda: self.statusBar().showMessage('остановлен'))
    @thread            
    def Start(self):
        
        r = self.ui.textEdit.toPlainText()
        strorint1.r = int(r)
        strorint1.strorint()
    def Stop(self):
        n = self.ui.textEdit.toPlainText()
        #strorint1.n = int(r)
        strorint1.stop()
        
if __name__=="__main__":
    app = QtWidgets.QApplication(sys.argv)
    myapp = MainWindow()
    myapp.show()
    sys.exit(app.exec_())
    

Отредактировано Venus (Июль 17, 2018 15:22:05)

Офлайн

#9 Июль 17, 2018 16:16:24

rami
Зарегистрирован: 2018-01-08
Сообщения: 281
Репутация: +  72  -
Профиль   Отправить e-mail  

QSpinBox Qt5 передача значения в питон

Venus
старт нажимаешь и зависает, хотя скрипт работает
Функция strorint() рекурсивно себя вызывает. Это так надо?

Офлайн

#10 Июль 17, 2018 16:39:42

PEHDOM
Зарегистрирован: 2016-11-28
Сообщения: 2196
Репутация: +  294  -
Профиль   Отправить e-mail  

QSpinBox Qt5 передача значения в питон

Venus
добавил в код @thread выдало TypeError: Start() takes 1 positional argument but 2 were given, откуда второй вылез
давай все же по порядку, начнем с внешнего модуля, насколькко критично делать цикл рекусией?
Я понимаю что это просто заглушка модуля, поэтому и спрашиваю, есть ли для этого какие то объективные причины? Почему просто не сделать while флаг: ? Просто пайтон ограничивает глубину рекурсии(по умолчанию 1000) и в один момент поток отвалится выбросив исключением.
Venus
вот main
конкретно в такой реализации поменять def Start на
     def Start(self):
        r = self.ui.textEdit.toPlainText()
        strorint1.r = int(r)
        self.sec_thread = Thread(target = strorint1.strorint)
        self.sec_thread.start()
оно будет работать , но уж насколько правильно ХЗ потому как есть пару вопросов по архитектуре.
В конкретном примере не предусмотрен выход из бесконечной рекурсии, поэтому после запуска, второй поток уходит в бесконечную рекурсиию, а def Stop и strorint1.stop() не делают ничего.
При смене текста , поток работает со старым значением, МБ так и задумывалось.
Использование глобальных переменных без особых на то нужд не есть хорошо. почему нельзя передать их аргументом в strorint? или сделать классом , если нужно менять атрибуты на лету.



==============================
Помещайте код в теги:
[code python][/code]
Бериегите свое и чужое время.

Офлайн

  • Начало
  • » GUI
  • » QSpinBox Qt5 передача значения в питон[RSS Feed]

Board footer

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

Powered by DjangoBB

Lo-Fi Version