Hi,
i am trying to implement a multithreaded QT5 GUI, but it seems that i some issues using the connection between signals and slots. It's working perfectly in C++.
I create a worker thread (worker1) that generate a integer and should pass it through an argument (emit) to the main GUI:
The code looks like this :
#![windows_subsystem = "windows"]
// Includes /////////////////////////////////////
use cpp_core::{Ptr, Ref, StaticUpcast};
use qt_core::{qs, slot, QBox, QObject, Signal, SlotNoArgs, SlotOfI64, SignalOfI64, QString, QThread, QVariant};
use qt_widgets::{QApplication, QLineEdit, QPushButton,QVBoxLayout, QWidget,};
use std::rc::Rc;
use std::{time, thread};
// Worker definition ////////////////////////////
struct Worker1 {
widget: QBox<QObject>,
val: QBox<SignalOfI64>
}
impl StaticUpcast<QObject> for Worker1 {
unsafe fn static_upcast(ptr: Ptr<Self>) -> Ptr<QObject> {
ptr.widget.as_ptr().static_upcast()
}
}
impl Worker1 {
fn new() -> Rc<Worker1> {
unsafe {
let widget = QObject::new_0a();
let val = SignalOfI64::new();
let this = Rc::new(Self {
widget, val,
});
this
}
}
// #[signal(SignalOfI64)]
unsafe fn update_val(self: &Rc<Self>, val: QBox<SignalOfI64>) {}
#[slot(SlotNoArgs)]
unsafe fn do_work(self: &Rc<Self>) {
// let t = time::Duration::from_millis(10);
// do work here
for i in 0..100 {
self.val.emit(i);
// self.update_val(&val).SignalOfI64.emit();
}
}
} // end impl worker1
// QT5 GUI definition////////////////////////////
struct Form {
widget: QBox<QWidget>,
line_edit: QBox<QLineEdit>,
startbutton: QBox<QPushButton>,
stopbutton: QBox<QPushButton>,
}
impl StaticUpcast<QObject> for Form {
unsafe fn static_upcast(ptr: Ptr<Self>) -> Ptr<QObject> {
ptr.widget.as_ptr().static_upcast()
}
}
impl Form {
fn new() -> Rc<Form> {
unsafe {
let widget = QWidget::new_0a();
let layout = QVBoxLayout::new_1a(&widget);
let line_edit = QLineEdit::new();
layout.add_widget(&line_edit);
let startbutton = QPushButton::from_q_string(&qs("Start"));
startbutton.set_enabled(true);
layout.add_widget(&startbutton);
let stopbutton = QPushButton::from_q_string(&qs("Stop"));
stopbutton.set_enabled(false);
layout.add_widget(&stopbutton);
widget.show();
let this = Rc::new(Self {
widget, startbutton, stopbutton, line_edit,
});
this.init();
this
}
}
unsafe fn init(self: &Rc<Self>) {
self.startbutton.clicked().connect(&self.slot_on_startbutton_clicked());
}
#[slot(SlotOfI64)]
unsafe fn updateval(self: &Rc<Self>, val: Ref<i64>) {
self.line_edit.set_text(&qs(val.to_string()));
}
#[slot(SlotNoArgs)]
unsafe fn on_startbutton_clicked(self: &Rc<Self>) {
self.stopbutton.set_enabled(true);
// Create Thread & Workers
let thread1 = QThread::new_0a();
let worker1 = Worker1::new();
// Connect signals to slots
worker1.move_to_thread(thread1);
thread1.started().connect(worker1.do_work());
worker1.update_val().connect(self.updateval());
self.stopbutton.clicked().connect(thread1.finished());
thread1.start_0a();
}
}
// Main Definition///////////////////////////////
fn main() {
QApplication::init(|_| unsafe {
let _form = Form::new();
QApplication::exec()
})
}
Any help would be be very appreciated. Don't be too hard with me it's my first utilisation of Qthread with Rust.
Than you in advance !
Best Regards.
Olivier.