2013-02-13 7 views
1

J'utilise Qt pour générer une fenêtre. De plus, j'utilise libnfc pour avoir accès à un lecteur nfc, jusqu'ici tout va bien. Dans mon auto-écrit nfc-class je génère un nouveau thread, ce thread interroge de nouvelles balises sur le lecteur. S'il y a une nouvelle étiquette, le thread commencera un événement de signal pour la MainWindow. Dans la fenêtre principale j'ai juste un QWebView qui montrera différents sites Web sur différents états (après le début, le nouveau tag, le tag enlevé), juste des trucs basiques.Qt MainWindow ne met pas à jour

Mon problème est maintenant: que la fenêtre principale (ou QWebView) n'est pas mise à jour. Si je passe à un autre programme et que je retourne à mon application, la fenêtre sera mise à jour. Je cherchais déjà avec google et j'essayais des trucs différents mais rien n'aide.

Voici le code de fil:

class NFC_Thread : public QThread 
{ 
    Q_OBJECT 
public: 
    NFC_Thread(NFC_Reader * Reader); 
    void run(); 

signals: 
    void NewTarget(nfc_target Target); 
    void TargetRemoved(nfc_target Target); 

private: 
    int mError; 
    bool mStopPolling; 
}; 

void NFC_Thread::run() 
{ 
    mError = 0; 
    mStopPolling = false; 
    while(!mStopPolling) 
    { 
     nfc_target Target; 
     mError = nfc_initiator_poll_target(mReader->GetDevice(), nmModulations, szModulations, mPollNr, mPollPeriod, &Target); 
     if(mError > 0) 
     { 
      cout << "NFC: found target" << endl; 
     } 
#warning Bug in driver: Timeout generate a NFC_EIO Error, 'https://code.google.com/p/libnfc/issues/detail?id=224' 
     else if(mError > 0) 
     { 
      cout << "NFC: Error" << endl; 
      mStopPolling = true; 
     } 
     else 
     { 
      cout << "NFC: no target found" << endl; 
     } 
    } 
} 

Code de MainWindow:

class MainWindow : public QMainWindow 
{ 
    Q_OBJECT 

public: 
    explicit MainWindow(QWidget *parent = 0); 
    ~MainWindow(); 

public slots: 
    void SetNewTarget(nfc_target Target); 
    void doTargetRemoved(nfc_target Target); 

private: 
    bool event(QEvent *event); 
    void resizeEvent(QResizeEvent *); 
    void adjust(); 

    Ui::MainWindow *ui; 
    QWebView * mWebView; 
}; 

MainWindow::MainWindow(QWidget *parent) : 
    QMainWindow(parent), 
    ui(new Ui::MainWindow) 
{ 
    ui->setupUi(this); 
    mWebView = new QWebView(this); 
    mWebView->load(QUrl("http://www.pbuchegger.at/")); 
    mWebView->show(); 
} 

void MainWindow::SetNewTarget(nfc_target Target) 
{ 
    QString str = "NEW TARGET: \n"; 
    { 
     char * s; 
     str_nfc_target(&s, Target, false); 
     str += s; 
     delete s; 
    } 
    //cout << "NFC: Target: " << str << endl; 
    mWebView->load(QUrl("http://www.google.at")); 
    update(); 
    repaint(); 
    mWebView->update(); 
    qApp->processEvents(); 
    /*QMessageBox msgBox; 
    msgBox.setText(str); 
    msgBox.exec();*/ 
} 

void MainWindow::doTargetRemoved(nfc_target Target) 
{ 
    QString str = "TARGET REMOVED: \n"; 
    { 
     char * s; 
     str_nfc_target(&s, Target, false); 
     str += s; 
     delete s; 
    } 
    //cout << "NFC: Target: " << str << endl; 
    mWebView->load(QUrl("http://www.cde.at")); 
    update(); 
    repaint(); 
    mWebView->update(); 
    qApp->processEvents(); 
    /*QMessageBox msgBox; 
    msgBox.setText(str); 
    msgBox.exec();*/ 
} 

bool MainWindow::event(QEvent *event) 
{ 
    if(event->type() == QEvent::Resize) 
    { 
     adjust(); 
     return true; 
    } 
    return false; 
} 

void MainWindow::resizeEvent(QResizeEvent *) 
{ 
    adjust(); 
} 

void MainWindow::adjust() 
{ 
    mWebView->setGeometry(0, 0, ui->centralWidget->geometry().width(), ui->centralWidget->geometry().height()); 
} 

code principal:

int main(int argc, char *argv[]) 
{ 
    QApplication a(argc, argv); 
    qRegisterMetaType<nfc_target>("nfc_target"); 

    MainWindow w; 
    w.setWindowState(Qt::WindowMaximized); 

    NFC_Reader Reader; 
    nfc_device_string devs; 
    size_t nr; 
    QString str = ""; 

    Reader.GetDevices(devs, nr); 
    if(nr > 0) 
    { 
     if(!Reader.InitReader(NULL)) 
     { 
      str += "Error on init!"; 
     } 
     else 
     { 
      Reader.Start_Polling(); 
      str += "Started Polling!"; 
     } 
    } 
    else 
    { 
     str += "No Device found!"; 
    } 
    w.SetText(str); 

    SignalHelper Helper; 

    QObject::connect(Reader.GetThread(), SIGNAL(NewTarget(nfc_target)), &Helper, SLOT(doNewTarget(nfc_target))); 
    QObject::connect(Reader.GetThread(), SIGNAL(TargetRemoved(nfc_target)), &Helper, SLOT(doTargetRemoved(nfc_target))); 
    QObject::connect(&Helper, SIGNAL(NewTarget(nfc_target)), &w, SLOT(SetNewTarget(nfc_target))); 
    QObject::connect(&Helper, SIGNAL(TargetRemoved(nfc_target)), &w, SLOT(doTargetRemoved(nfc_target))); 

    w.show(); 
    int ret = a.exec(); 
    Reader.Abort_Polling(); 
    return ret; 
} 

Comme u peut voir, j'ai une classe "aide", cette La classe est en train d'obtenir le signal dans un slot et de recommencer un signal qui sera transmis à la mainwindow. Si je veux transférer le signal directement à la fenêtre principale, rien ne se passe (comme le signal n'est pas déclenché), mais je le vérifiais avec la boîte Qt-About, et la boîte apparaît.

Classe d'assistance:

class SignalHelper : public QObject 
{ 
    Q_OBJECT 
public slots: 
    void doNewTarget(nfc_target Target); 
    void doTargetRemoved(nfc_target Target); 
signals: 
    void NewTarget(nfc_target Target); 
    void TargetRemoved(nfc_target Target); 
}; 

void SignalHelper::doNewTarget(nfc_target Target) 
{ 
    emit NewTarget(Target); 
} 

void SignalHelper::doTargetRemoved(nfc_target Target) 
{ 
    emit TargetRemoved(Target); 
} 

aucune erreur du compilateur ou des erreurs de l'éditeur de liens. ce code montre juste les choses importantes, toutes les choses sans importance sont enlevées. pour votre information le dossier du projet:

QT += core gui testlib 
QT += webkit 

greaterThan(QT_MAJOR_VERSION, 4) { 
QT += widgets 
} 

TARGET = NFC_GUI 
TEMPLATE = app 

SOURCES += main.cpp \ 
mainwindow.cpp \ 
nfc_thread.cpp \ 
nfc_reader.cpp \ 
signal_helper.cpp 

HEADERS += mainwindow.h nfc_thread.h nfc_reader.h signal_helper.h 

FORMS += mainwindow.ui 

LIBS += -lnfc 
+0

Il est peut-être parce que votre MainWindow tombe juste chaque événement, sauf pour la redimensionner l'événement. Au lieu de cela, vous devriez le passer au parent ou à la classe de base si vous ne voulez pas le traiter vous-même. – scai

+0

non, je testais cela. un slot de signal est une chose de slot de signal et n'appelera pas la fonction event(). – peterus

+3

Votre fonction 'bool MainWindow :: event (Evénement QEvent *)' devrait retourner 'QMainWindow :: event (event);' au lieu de retourner 'false' de toute façon. Ceci est complètement indépendant des signaux et des slots. –

Répondre

2

Faire mon commentaire une réponse:

Votre fonction

bool MainWindow::event(QEvent *event) 
{ 
    if(event->type() == QEvent::Resize) 
    { 
     adjust(); 
     return true; 
    } 
    return false; 
} 

mange tout événement qui est traité dans QMainWindow sauf pour QEvent::Resize. Vous devez appeler le comportement par défaut pour les événements que vous n'êtes pas intéressé par:

bool MainWindow::event(QEvent *event) 
{ 
    if(event->type() == QEvent::Resize) 
    { 
     adjust(); 
     return true; 
    } 
    // call the parent implementation 
    return QMainWindow::event(event); 
} 

Notez que vous pouvez aussi tout simplement mettre en œuvre QWidget::resizeEvent:

void MainWindow::resizeEvent(QResizeEvent *event) 
{ 
    adjust(); 

    QMainWindow::resizeEvent(event); 
} 
0

Si vous appelez fentes de signaux entre les différents threads, vous avez besoin de faire les appels de connexion avec Qt :: QueuedConnection comme le type de connexion.