別のスレッドからシグナルを発信しようとすると、セグメンテーション違反が発生しますが、理由はわかりません。
シグナルとスロットはどちらも同じクラスで定義され、メインの GUI スレッドで実行されますが、ブースト スレッド タイプのスレッドによって制御される別の関数で発行を呼び出します。
私は Qt4 を使用しており、Ubuntu 10.04 が私の OS です。この関数は、シグナルを発信している別のスレッドから呼び出されます。
void MyMapItem::updateMap(std::vector<int> data11)
{
my_mutex.lock();
cout<< "i am in updatemap"<<endl;
data12.clear();
data12=data11;
cout<<"size of data"<<data12.size()<<endl;
my_mutex.unlock();
emit mera_signal();
}
MyMapItem::MyMapItem(QGraphicsItem *parent )
{
QObject::connect(this,SIGNAL(mera_signal()),this,SLOT(mera_slot()),Qt::BlockingQueuedConnection );
}
上記は私のQtクラスのコンストラクタです。
void MyMapItem::mera_slot()
{
cout<< "signal is emitted"<<endl;
qDebug() << "Date:";
}
上記はスロットの定義です。とりあえずメッセージを出力しています。
流れをもう少し詳しく説明します。
- ROS に接続され、トピックにサブスクライブする、今
MapGenerator
から継承されるクラスが 1 つあります。QThread
- ここで、両方
MyMapitem
から継承された別のクラスを取得し、このクラスでスロットとシグナルを定義しました。QObject
GraphicsItem
Mainwindow
から継承された 3 番目のクラスを取得Qobject
し、グラフィックス シーンをセットアップしますmymapitem
。- ここで私がやって
main
いることは、オブジェクトを作成Mapgenerator
してスレッドを開始することです。 - 次に、 のオブジェクトを作成します
Mainwindow
。 - そのため、
Mapgenerator
スレッドが開始すると、ROS からデータをサブスクライブし、関数を呼び出してMyMapItem
そこにデータを転送します。
ここでは、新しいデータが到着したことを知るために信号を送信したいと考えています。Mainwindow
次に、コンストラクターで既にシーンにあるアイテムを更新します。接続はMyMapItem
クラス コンストラクターで行われます。
ありがとう ここにスレッドとメインウィンドウを作成しているメインメソッドを投稿します。
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
ros::init(argc,argv,"last");
MapGenerator::MapGenerator mg(argc,argv);
//boost::thread ros_thread(boost::bind(&MapGenerator::init2, &mg));
mg.start(); // Qthread
MainWindow w(argc,argv);
w.show();
return a.exec();
}
ここでメインウィンドウコンストラクターで Mapitem オブジェクトを作成しました
MainWindow::MainWindow( int argc, char **argv, QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
this->setWindowTitle("My app");
mapitem = new MyMapItem();
scene = new QGraphicsScene(0,0,4000,4000);
ui->graphicsView->setScene(scene);
scene->addItem(mapitem);
}