Найти - Пользователи
Полная версия: PyQt4: Доступ к элементам формы через внешние методы
Начало » GUI » PyQt4: Доступ к элементам формы через внешние методы
1
nd7
Друзья, как через сторонний метод передавать данные на форму?
Так понимаю, здесь стоит рыть в сторону сигналов, но всё никак не разберусь, как и зачем их нужно подключать.
На данном примере хотелось бы устанавливать надпись на кнопку из QLineEdit, но чтобы всё это шло через Cycle, а не через методы MyWindow.
from PyQt4 import QtCore, QtGui
from time import sleep
import sys
global i; i=0
def Cycle():
    while(True):
        i+=1
        print(i)
        sleep(1)
class MyThread(QtCore.QThread):
    def __init__(self, parent=None):
        QtCore.QThread.__init__(self, parent)
    def run(self):
        Cycle()
class MyWindow(QtGui.QWidget):
    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent)
        self.button=QtGui.QPushButton("START")
        self.label=QtGui.QLabel("")
        self.txtName = QtGui.QLineEdit('', self)
        self.label.setAlignment(QtCore.Qt.AlignCenter)
        self.vbox=QtGui.QVBoxLayout()
        self.vbox.addWidget(self.button)
        self.vbox.addWidget(self.label)
        self.vbox.addWidget(self.txtName)
        self.setLayout(self.vbox)
        self.connect(self.button,QtCore.SIGNAL("clicked()"),self.on_clicked)
        self.mythread=MyThread()
    def setTextOnButton(self):
        self.button.setText(str(i))
    def on_clicked(self):
        self.setTextOnButton()
        self.mythread.start()
if __name__ == "__main__":
    app=QtGui.QApplication(sys.argv)
    window=MyWindow()
    window.resize(250, 50)
    window.show()
    sys.exit(app.exec_())
alexbadaloff
Про global вам бы почитать как использовать. Да и про классы с объектами.

И если я правильно понял ваш вопрос, то в Cycle вам нужно просто обратиться к button из класса MyWindow и присвоить ему нужный текст.

from PyQt4 import QtCore, QtGui
from time import sleep
import sys
i=0
def Cycle():
    global i
    while(True):
        i+=1
        print(i)
        window.button.setText(str(i))
        sleep(1)
class MyThread(QtCore.QThread):
    def __init__(self, parent=None):
        QtCore.QThread.__init__(self, parent)
    def run(self):
        Cycle()
class MyWindow(QtGui.QWidget):
    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent)
        self.button=QtGui.QPushButton("START")
        self.label=QtGui.QLabel("")
        self.txtName = QtGui.QLineEdit('', self)
        self.label.setAlignment(QtCore.Qt.AlignCenter)
        self.vbox=QtGui.QVBoxLayout()
        self.vbox.addWidget(self.button)
        self.vbox.addWidget(self.label)
        self.vbox.addWidget(self.txtName)
        self.setLayout(self.vbox)
        self.connect(self.button,QtCore.SIGNAL("clicked()"),self.on_clicked)
        self.mythread=MyThread()
    def on_clicked(self):
        self.mythread.start()
if __name__ == "__main__":
    app=QtGui.QApplication(sys.argv)
    window=MyWindow()
    window.resize(250, 50)
    window.show()
    sys.exit(app.exec_())
alexbadaloff
nd7
хотелось бы устанавливать надпись на кнопку из QLineEdit, но чтобы всё это шло через Cycle
Тогда так:
def Cycle():
    window.button.setText(window.txtName.text())
nd7
alexbadaloff, спасибо огромное, помогло.

alex925
nd7
Глобальные переменные это прямой путь в ад программиста, это во 1, во 2 как ты правильно понял твоя проблема решается с помощью сигналов.
Вот пример кода:
import sys
import time
import threading
 
from PyQt4 import QtGui, QtCore
 
 
def thread(my_func):
    """
    Запускает функцию в отдельном потоке
    """
    def wrapper(*args, **kwargs):
        my_thread = threading.Thread(target=my_func, args=args, kwargs=kwargs)
        my_thread.start()
    return wrapper
 
 
@thread
def processing(signal):
    """
    Эмулирует обработку (скачивание) каких-то данных
    """
    res = [i for i in 'hello']
    time.sleep(5)
    signal.emit(res)  # Посылаем сигнал в котором передаём полученные данные
 
 
class MyWidget(QtGui.QWidget):
    my_signal = QtCore.pyqtSignal(list, name='my_signal')
    def __init__(self, parent=None):
        super(MyWidget, self).__init__(parent)
        self.mainLayout = QtGui.QHBoxLayout()
        self.setLayout(self.mainLayout)
        self.b = QtGui.QPushButton("Emit your signal!", self)
        self.mainLayout.addWidget(self.b)
        self.b.clicked.connect(lambda: processing(self.my_signal))  # При нажатии на кнопку запускаем обработку данных
        self.my_signal.connect(self.mySignalHandler, QtCore.Qt.QueuedConnection)  # Обработчик сигнала
    def mySignalHandler(self, data):  # Вызывается для обработки сигнала
        print(data)
 
if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)
    window = MyWidget()
    window.show()
    app.exec_()

Пример абстрактный, но в полной степени решает твою задачу. Что не понятно спрашивай.

Тебе нужно будет в этом примере только обработчик сигнала поменять. В твоём случае он будет получать данные сгенерированные в другом потоке и менять надпись кнопки.
nd7
alex925, до декораторов и лямбд еще не доходил, но попробую разобраться.
Rodegast
> вам нужно просто обратиться к button из класса MyWindow и присвоить ему нужный текст.

Ничего себе! Неужели в Qt работу с потоками наладили, хотя я бы ещё не рисковал такое делать. Про сигналы смотри примеры из PyQt и читай этот форум. Тема очень заезжена.
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