Solved Is it possible to create a pointer to the main window?
-
Hi I have a Qt Application and ROS Action Server which takes in requests and invoke some features of my application like displaying dialog windows etc,.
My Main method is something like this:
int main(int argc, char *argv[]) { qInstallMessageHandler(myMessageOutput); if( !ros::isInitialized() ) { ros::init( argc, argv, "APS");//, ros::init_options::AnonymousName ); ros::param::set("/use_gui", true); } QApplication a(argc, argv); w = new MainWindow; w->show(); GUIActionServer as_(ros::this_node::getName(), w);// Here I start my action server based on the reqests i have to invoke some functionalites in my Main window int result = a.exec(); delete w; w=NULL; return result;
}
GUIActionServer.h is as follows:
#ifndef GUIACTIONSERVER_H #define GUIACTIONSERVER_H #include <ros/ros.h> #include <actionlib/server/simple_action_server.h> #include <aps_msgs/MoveArmAction.h> #include <moveit_msgs/MoveItErrorCodes.h> #include <configdialog.h> #include <QDebug> #include "mainwindow.h" #include <QObject> class GUIActionServer : public QObject { Q_OBJECT public: GUIActionServer(std::string name, MainWindow* w); ~GUIActionServer(); void executeCB(const aps_msgs::MoveArmGoalConstPtr &goal); protected: ros::NodeHandle nh_; // NodeHandle instance must be created before this line. Otherwise strange error may occur. actionlib::SimpleActionServer<aps_msgs::MoveArmAction> as_; std::string action_name_; // create messages that are used to published feedback/result aps_msgs::MoveArmFeedback feedback_; aps_msgs::MoveArmResult result_; MainWindow* sw; }; #endif // GUIACTIONSERVER_H
GUIActionServer.cpp is as follows:
#include "guiactionserver.h" GUIActionServer::GUIActionServer(std::string name, MainWindow* w) : as_(nh_, name, boost::bind(&GUIActionServer::executeCB, this, _1), false), action_name_(name) { as_.start(); sw = w; } GUIActionServer::~GUIActionServer(){}; void GUIActionServer::executeCB(const aps_msgs::MoveArmGoalConstPtr &goal) { // helper variables ros::Rate r(1); bool success = true; feedback_.state = "In Execute Callback method"; std::cout << goal->exec_path.at(0).position.x << std::endl; as_.publishFeedback(feedback_); r.sleep(); if(sw){ sw->testDialog(); } sw = NULL; success = true; if(success) { result_.error_code.val = 1; ROS_INFO("%s: Succeeded", action_name_.c_str()); // set the action state to succeeded as_.setSucceeded(result_); } }
When I am using the above code application is not stable and got the following error
QObject::connect: Cannot queue arguments of type 'QTextBlock'
(Make sure 'QTextBlock' is registered using qRegisterMetaType().)
QObject::connect: Cannot queue arguments of type 'QTextCursor'
(Make sure 'QTextCursor' is registered using qRegisterMetaType().)
Segmentation fault (core dumped)Any ideas will be much appreciated. Thanks in advance
-
Hi,
Looks like you are already doing something fishy with some signals and slots. Can you show the code where you establish these connections ?
-
GUIActionServer as_(ros::this_node::getName(), w);// Where i creates my obj to Action Server and pass the mainwindow 'w'.
// Assigns to another pointer in GUIActionServer Mainwindow* sw;
sw = w;// Calls the testDialog method in GUIActionServer::executeCB function which popsup Dialog in mainwindow
if(sw){
sw->testDialog();
}Hope this looks simple rather than going through the whole code...
-
Except your error has nothing to do with the code you posted and more likely with the rest your didn't post.
Like the error says, you are trying to use a type that is not known to the signal and slots system so you likely did some connect calls somewhere in your code. That's the part that must be checked.
-
If I remove my GUIActionServer then the application works fine. This error popsup only when i include this GUIActionServer thingy. I suspect there might be some wrong thing in the way i work with threads and pointers.
I have one General question MainWindow has its own thread and GUIActionServer will also up and running. Can i invoke the main thread whenever my Action Server wants to talk to it?
-
No, you cannot modify directly GUI elements from another thread. You should use signals and slots for that.
But still, the connect error should be investigated.
-
In that case, I think this might be causing the error:
void MainWindow::testDialog(){ ConfigDialog cond; qInfo() << "From Action Server obj is created"; cond.setMode("View"); qInfo() << "Mode is " << cond.mode.c_str(); cond.updateConfigDialog(); cond.setModal(false); cond.exec(); }
I am creating a new dialog whenever i receive a request from the action server. Mightbe it is failing here to connect Qobjects because this is a pointer to mainwindow. Am I correct?
-
No you're not.
Connection error like that have nothing to do with the fact that you are using a pointer for your MainWindow.
Again, do you have any connect statement somewhere in your code ?
-
I have these connections which are present in the ConfigDialog.ui
<connections> <connection> <sender>buttonBox</sender> <signal>accepted()</signal> <receiver>ConfigDialog</receiver> <slot>accept()</slot> <hints> <hint type="sourcelabel"> <x>248</x> <y>254</y> </hint> <hint type="destinationlabel"> <x>157</x> <y>274</y> </hint> </hints> </connection> <connection> <sender>buttonBox</sender> <signal>rejected()</signal> <receiver>ConfigDialog</receiver> <slot>reject()</slot> <hints> <hint type="sourcelabel"> <x>316</x> <y>260</y> </hint> <hint type="destinationlabel"> <x>286</x> <y>274</y> </hint> </hints> </connection> </connections>
Other than these i haven't defined any custom connections. I have searched my code but I am unable to find QTextBlock and QTextCursor defined
-
I got it..... I have made a mistake I was calling the testDialog using normal method instead of signals and slots. Now i have connected as follows:
GUIActionServer::GUIActionServer(std::string name, MainWindow* w) : as_(nh_, name, boost::bind(&GUIActionServer::executeCB, this, _1), false), action_name_(name) { as_.start(); sw = w; // Connecting using signals and slots here // ActionInvoked is a signal in GUIActionServer and testDialog is a public slot in MainWindow QObject::connect(this, &GUIActionServer::actionInvoked, w, &MainWindow::testDialog); } GUIActionServer::~GUIActionServer(){}; void GUIActionServer::executeCB(const aps_msgs::MoveArmGoalConstPtr &goal) { // helper variables ros::Rate r(1); bool success = true; feedback_.state = "In Execute Callback method"; std::cout << goal->exec_path.at(0).position.x << std::endl; as_.publishFeedback(feedback_); r.sleep(); // If main window is opened then I will call the signal. if(sw){ actionInvoked(); } sw = NULL; success = true; if(success) { result_.error_code.val = 1; ROS_INFO("%s: Succeeded", action_name_.c_str()); // set the action state to succeeded as_.setSucceeded(result_); } }
The previous issue is related to threading i guess.... Now I am not receiving any error the code works fine. Thank you for your support @SGaist