Qt を使用してウィンドウを生成しています。さらに、libnfc を使用して nfc リーダーにアクセスしていますが、これまでのところ問題ありません。自分で書いた nfc クラスでは、新しいスレッドを生成します。このスレッドは、リーダーの新しいタグをポーリングしています。新しいタグがある場合、スレッドは MainWindow のシグナル イベントを開始します。メインウィンドウには、さまざまな状態 (開始後、新しいタグ、タグが削除された後) のさまざまな Web サイトを表示する QWebView だけがあり、本当に基本的なものです。
私の問題は、メイン ウィンドウ (または QWebView) が更新されていないことです。別のプログラムに切り替えてアプリに戻ると、ウィンドウが更新されます。私はすでにグーグルで検索していて、別のものを試していましたが、何も役に立ちません。
ここにスレッドコード:
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;
}
}
}
メインウィンドウ コード:
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());
}
メインコード:
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;
}
ご覧のとおり、「ヘルパー」クラスがあります。このクラスは、スロットで信号を取得し、メインウィンドウに転送される信号を再度開始しています。シグナルをメインウィンドウに直接転送したい場合、何も起こりません (シグナルが発生しないなど) が、Qt-About ボックスでチェックしていたところ、ボックスが表示されています。
ヘルパー クラス:
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);
}
コンパイラ エラーやリンカ エラーはありません。このコードは重要なものだけを示しており、重要でないものはすべて削除されています。参考までに、プロジェクトファイル:
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