Пример с потоком
PostPosted: 26 Jun 2016, 09:22
by mkornevich3
Создайте пожалуйста пример: В окне многострочное поле и кнопка при нажатии на которую запускается поток который загружает с гугла главную страницу и вставляет в многострочное поле. Главное чтоб вставка в поле происходила в потоке.
Re: Пример с потоком
PostPosted: 28 Jun 2016, 20:50
by WxMaper
- Code:
<?php
class WebWorker extends QObject {
public $signals = [
"finished(string)"
];
public function __construct() {
parent::__construct();
}
public function get_slot($sender, $url) {
sleep(5); // для наглядности
$content = file_get_contents($url);
$this->emit("finished(string)", [ $content ]);
}
public function get($url) {
sleep(5); // для наглядности
$content = file_get_contents($url);
$this->emit("finished(string)", [ $content ]);
}
}
class MainWindow extends QWidget {
private $worker;
private $thread;
private $textEdit;
private $lineEdit;
private $button;
public $signals = [
"getContents(string)"
];
public function __construct() {
parent::__construct();
$this->initComponents();
}
private function initComponents() {
$this->thread = new QThread;
$this->thread->start();
$this->worker = new WebWorker;
$this->worker->moveToThread($this->thread);
// создаём виджеты
$this->textEdit = new QTextEdit;
$this->lineEdit = new QLineEdit;
$this->lineEdit->text = "http://phpqt.ru/";
$this->button = new QPushButton("Get HTML");
// vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
// vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
/** Вся проблема в том, что on*-сигналы всегда выполняются в текущем потоке,
поэтому такой код:
$this->button->onClicked = function() {
$this->worker->get($this->lineEdit->text);
};
хоть и является рабочим, но будет замораживать форму.
Связь событий для работы с потоками нужно создавать через функцию connect()
Это пример использования сигнала onClicked() для передачи строкового параметра
объекту, находящемуся в другом потоке: при срабатывании сигнала onClicked(),
мы генерируем новый сигнал с нужными параметрами,
который был зарегистрирован в переменной $signals. (эта переменная брабатывается движком)
*/
$this->button->onClicked = function() {
$this->emit("getContents(string)", [ $this->lineEdit->text ]);
};
// затем мы просто соединяем нужные сигналы со слотами через функцию connect()
connect($this->worker, SIGNAL("finished(string)"),
$this, SLOT("finished_slot(string)"));
connect($this, SIGNAL("getContents(string)"),
$this->worker, SLOT("get_slot(string)"));
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// создаём компоновщик и кидаем на него виджеты
$this->layout = new QVBoxLayout;
$this->layout->addWidget($this->textEdit);
$this->layout->addWidget($this->lineEdit);
$this->layout->addWidget($this->button);
}
public function finished_slot($sender, $content) {
pre($content);
}
}
$mainWindow = new MainWindow;
$mainWindow->show();
qApp::exec();
Этот код не будет работать в снапшоте PQBuilder 0.5.3 от 23.06.2016 (обнаружен баг)
Но будет работать в версии
0.5.2. В следующих версиях/снапшотах баг будет исправлен, на этой неделе постараюсь выложить исправленную сборку.