ma il problema è che, non riesco a raggiungere il ana-> UI-> horizontalLayout_4-> addWidget (etichetta);
Inserire le modifiche dell'interfaccia utente in uno slot nella finestra principale e collegare un segnale di filo a quello slot, è probabile che funzioni. Penso che solo il thread principale abbia accesso all'interfaccia utente di Qt. Pertanto, se si desidera la funzionalità della GUI, deve essere presente e può essere segnalata solo da altri thread.
OK, ecco un semplice esempio. A proposito, il tuo scenario non ha davvero bisogno di estendere lo QThread
- quindi è meglio non farlo, a meno che tu non debba farlo. Ecco perché in questo esempio, io uso un normale QThread
con un lavoratore in base QObject
invece, ma il concetto è lo stesso se si sottoclasse QThread
:
L'interfaccia utente principale:
class MainUI : public QWidget
{
Q_OBJECT
public:
explicit MainUI(QWidget *parent = 0): QWidget(parent) {
layout = new QHBoxLayout(this);
setLayout(layout);
QThread *thread = new QThread(this);
GUIUpdater *updater = new GUIUpdater();
updater->moveToThread(thread);
connect(updater, SIGNAL(requestNewLabel(QString)), this, SLOT(createLabel(QString)));
connect(thread, SIGNAL(destroyed()), updater, SLOT(deleteLater()));
updater->newLabel("h:/test.png");
}
public slots:
void createLabel(const QString &imgSource) {
QPixmap i1(imgSource);
QLabel *label = new QLabel(this);
label->setPixmap(i1);
layout->addWidget(label);
}
private:
QHBoxLayout *layout;
};
... e il oggetto operaio:
class GUIUpdater : public QObject {
Q_OBJECT
public:
explicit GUIUpdater(QObject *parent = 0) : QObject(parent) {}
void newLabel(const QString &image) { emit requestNewLabel(image); }
signals:
void requestNewLabel(const QString &);
};
l'oggetto lavoratore viene creato e spostato in un altro filo, poi connessa allo slot che crea le etichette, allora il metodo newLabel
viene richiamato, che è solo un involucro per emettere il requestNewLabel
segnale e passare il percorso per l'immagine. Il segnale viene quindi passato dall'oggetto worker/thread allo slot dell'interfaccia utente principale insieme al parametro del percorso dell'immagine e una nuova etichetta viene aggiunta al layout.
Poiché l'oggetto di lavoro è stato creato senza genitore per poterlo spostare su un altro thread, colleghiamo anche il segnale thread-thread allo slot worker deleteLater()
.
Se sei come me e hai 10 minuti fino alla scadenza, ecco una soluzione più aggressiva: aggiungi un pulsante fittizio nella finestra principale (larghezza e altezza 0), ogni volta che devi aggiornare l'interfaccia utente dall'operatore emettere un evento click() nel worker e sovrascrivere il gestore di clic per quel pulsante per eseguire gli aggiornamenti. – cristid9