Как обратиться к переменной другого класса?
Работаю с PyQt5 на Python.
Есть классы MyWidget(QMainWindow) и ThreadClassCheck(QtCore.QThread).
В MyWidget открывается интерфейс с 2 полями ввода и 1 кнопкой. После нажатия на кнопку из первого (верхнего) поля ввода это слово переносится во второе поле ввода (при этом в первом это слово также остается).
Как можно в классе ThreadClassCheck(QtCore.QThread) обратиться к значению этих двух полей из класса MyWidget?
Дизайн t.ui:
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>491</width>
<height>276</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralwidget">
<widget class="QPushButton" name="pushButton">
<property name="geometry">
<rect>
<x>210</x>
<y>190</y>
<width>93</width>
<height>31</height>
</rect>
</property>
<property name="text">
<string>кнопка</string>
</property>
</widget>
<widget class="QLineEdit" name="lineEditInput">
<property name="geometry">
<rect>
<x>130</x>
<y>40</y>
<width>321</width>
<height>31</height>
</rect>
</property>
</widget>
<widget class="QLabel" name="label">
<property name="geometry">
<rect>
<x>50</x>
<y>40</y>
<width>51</width>
<height>31</height>
</rect>
</property>
<property name="styleSheet">
<string notr="true">font: 12pt "MS Shell Dlg 2";</string>
</property>
<property name="text">
<string>Ввод</string>
</property>
</widget>
<widget class="QLabel" name="label_2">
<property name="geometry">
<rect>
<x>50</x>
<y>120</y>
<width>71</width>
<height>31</height>
</rect>
</property>
<property name="styleSheet">
<string notr="true">font: 12pt "MS Shell Dlg 2";</string>
</property>
<property name="text">
<string>Вывод</string>
</property>
</widget>
<widget class="QLineEdit" name="lineEdit_2Output">
<property name="geometry">
<rect>
<x>130</x>
<y>120</y>
<width>321</width>
<height>31</height>
</rect>
</property>
</widget>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>491</width>
<height>26</height>
</rect>
</property>
</widget>
<widget class="QStatusBar" name="statusbar"/>
</widget>
<resources/>
<connections/>
</ui>
main.py:
from PyQt5.QtWidgets import QApplication, QMainWindow
from PyQt5 import QtCore
from PyQt5 import uic
import sys
import time
class ThreadClassCheck(QtCore.QThread):
signal = QtCore.pyqtSignal(str)
def __init__(self, checkword, parent=None):
super(ThreadClassCheck, self).__init__(parent)
self.is_going = True
self.checkword = checkword
def display(self):
print('ниже выведем первое поле')
print(self.lineEditInput.text())
def run(self):
while True:
# как здесь получить переменную значение из двух полей ввода?
# self.text1 = self.lineEditInput.text()
# self.text2 = self.lineEdit_2Output.text()
# в интерфейсе, но не в классе ThreadClass
ex = MyWidget() # экземпляр интерфейса
ThreadClassCheck.display(ex) # такой вызов тоже не работает, пустая строка
time.sleep(3)
sms = "check"
self.signal.emit(sms)
def stop(self):
self.is_going = False
self.terminate()
class MyWidget(QMainWindow):
def __init__(self):
super().__init__()
uic.loadUi('t.ui', self)
self.pushButton.clicked.connect(self.btn)
self.text2 = self.lineEdit_2Output.text()
self.text1 = self.lineEditInput.text()
def btn(self):
print('кнопка нажата, данные из первой строки:', self.text1)
print('кнопка нажата, данные из второй строки:', self.text2)
self.lineEdit_2Output.setText(self.text1) # из первого поля ввода переносим во второй
def except_hook(cls, exception, traceback):
sys.__excepthook__(cls, exception, traceback)
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = MyWidget()
ex.show()
sys.excepthook = except_hook
sys.exit(app.exec_())
Попробовал через экземпляр, но почему-то выводит пустую строку.
Ответы (1 шт):
Нельзя взаимодействовать в дополнительном потоке с виджетами. В Qt вы должны использовать сигналы и слоты.
Дополнительные потоки нужны если у вас есть какие-то длительны задачи или вычисления.
В том что вы описываете нет длительных вычислений и поэтому вам не нужен дополнительный поток, а достаточно
QTimer:
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow
from PyQt5.QtCore import QTimer
from PyQt5 import uic
class MyWidget(QMainWindow):
def __init__(self):
super().__init__()
uic.loadUi('t.ui', self)
self.lineEditInput.setFocus()
self.pushButton.clicked.connect(self.btn)
self.timer = QTimer()
self.timer.timeout.connect(self.btn)
self.timer.start(3000)
def btn(self):
print(f'Ввод : {self.lineEditInput.text()}')
# из первого поля ввода переносим во второй
self.lineEdit_2Output.setText(self.lineEditInput.text())
print(f'Выврд: {self.lineEdit_2Output.text()}')
self.lineEditInput.setFocus()
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = MyWidget()
ex.show()
sys.exit(app.exec_())
- Если вы хотите понять работу с дополнительными потоками - тогда так:
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow
from PyQt5.QtCore import QTimer, QThread, pyqtSignal
from PyQt5 import uic
class ThreadClassCheck(QThread):
signal = pyqtSignal(str)
def __init__(self, word, parent=None):
super(ThreadClassCheck, self).__init__(parent)
self.is_going = True
self.word = word
def run(self):
while self.is_going:
self.signal.emit(self.word)
self.msleep(3000)
def stop(self):
self.is_going = False
class MyWidget(QMainWindow):
def __init__(self):
super().__init__()
uic.loadUi('t.ui', self)
self.lineEditInput.setFocus()
self.lineEditInput.textChanged.connect(self.text_changed)
self.pushButton.setText('Start')
self.pushButton.clicked.connect(self.btn)
self.thread = ThreadClassCheck(self.lineEditInput.text())
self.thread.signal.connect(self.thread_check)
def text_changed(self, text):
self.thread.word = text
def thread_check(self, text):
self.lineEdit_2Output.setText(text)
def btn(self):
if self.pushButton.text() == 'Start':
self.thread.start()
self.thread.is_going = True
self.pushButton.setText('Stop')
self.lineEditInput.setFocus()
else:
self.thread.stop()
self.pushButton.setText('Start')
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = MyWidget()
ex.show()
sys.exit(app.exec_())
