QT, can't bind QProcess::finished(int,QProcess::ExitStatus) signal to lambda - qt

I'm using c++11, and QT 5.12.
I'm trying to connect to the QProcess::finished(int,QProcess::ExitCode) signal to a lambda, but using the code
QProcess PlayerProcess;
connect(PlayerProcess, &QProcess::finished,
[=](int exitCode, QProcess::ExitStatus exitStatus)
{
// Function body
}
the compiler says
../Qt/5.12.1/gcc_64/include/QtCore/qobject.h:300:13: note: no known conversion for argument 1 from ‘QProcess’ to ‘const Object* {aka const QProcess*}’
../Qt/5.12.1/gcc_64/include/QtCore/qobject.h:308:13: note: candidate: template<class Func1, class Func2> static typename std::enable_if<(QtPrivate::FunctionPointer<Func2>::ArgumentCount == -1), QMetaObject::Connection>::type QObject::connect(const typename QtPrivate::FunctionPointer<Func>::Object*, Func1, const QObject*, Func2, Qt::ConnectionType)
connect(const typename QtPrivate::FunctionPointer<Func1>::Object *sender, Func1 signal, const QObject *context, Func2 slot,
^~~~~~~
../Qt/5.12.1/gcc_64/include/QtCore/qobject.h:308:13: note: template argument deduction/substitution failed:
../Launcher/mainwindow.cpp:184:9: note: candidate expects 5 arguments, 3 provided
);
Googling a bit, the only related problems I could find were that the MainWindow class wasn't deriving from a QObject (but my MainWindow derives from QMainWindow that derives from QWidget), or that the compiler couldn't resolve the overloaded QProcess::finished signal (that could be either (int) or (int,QProcess::ExitCode), but for this I tried both the quickfixes I could find:
void (QProcess::* mySignal)(int, QProcess::ExitStatus) = &QProcess::finished;
auto mySignal2 = QOverload<int,QProcess::ExitStatus>::of(&QProcess::finished);
but using both the compiler error doesn't change.
What did I miss here?
Thanks in advance.

As #ymoreau said, the QObject::connect function needs parameters as pointers, so i changed the connect's first parameter with a &PlayerProcess.
Then, the overloading QProcess::finished problem was solved using one of the two explicit overload.

Related

Using a java method in Qt that returns double array

I want to use java code inside my Qt Android app.
So, I use a QAndroidJniObject with the method callMethod, and it is supposed to return a jdoubleArray.It takes a const char argument.
QAndroidJniObject javaCode = QAndroidJniObject("/myJavaCode");
jdoubleArray result = javaCode.callMethod<jdoubleArray>("detect", "([C)[D", buffer_java);
I don't know why but it doesn't compile, but I saw some examples with int that seemed to works fine.
error: undefined reference to '_jdoubleArray* QAndroidJniObject::callMethod<_jdoubleArray*>(char const*, char const*, ...) const'
Thanks for your answers
Pierre

c - Array of pointer to functions, having different number of arguments

I am making a simple scheduler that executes functions contained in a FIFO queue.
Those functions have a same return type int, but have different number of int arguments.
I tried to implement it this way, but it does not seem to work. The compiler forbids conversion between int(*)() , int(*)(int), int(*)(int, int), or to any of those sort. (Arduino Sketch compiler)
Is there a way to solve this problem, or could you recommend a better way around? Thanks!
My code:
typedef int (*fnptr)(); // Tried this!
int foo(int var) {
return 0;
}
int main() {
fnptr fp = &foo; // error: invalid conversion from
// 'int (*)(int)' to 'int (*)()'
// [-fpermissive]
return 0;
}
You can cast:
fnptr fp = reinterpret_cast<fnptr>(foo);
The ()s are the "function call operator", adding them makes no sense at all in this situation, it changes the expression from "take the address of this function" to "take the address of this function's return value".
Note that aboev I don't even include the &, this is because the name of a function acts pretty much like a function pointer so it's already an address.

Linking error when including <pcl/io/png_io.h> in more than one file

I wanted to use pcl::io::savePNGFile in two source-files in my code.
As soon as I include the required include in second source-file
# include <pcl/io/png_io.h>
the project doesn't compile.
The error message is:
/usr/include/pcl-1.7/pcl/io/png_io.h:86: multiple definition of `pcl::io::saveRgbPNGFile(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned char const*, int, int)'
I'm going to wrap the function in a class in order to include it only once in project. But I think it is not the best way. Am I doing something in a wrong way? Is there a better solution?
Thanks!
EDIT
Finally I've implemented a Q&D solution and wrapped the function (only for normal clouds)
cloudsaver.h
#ifndef CLOUDSAVER_H
#define CLOUDSAVER_H
#include <pcl/point_types.h>
#include <pcl/point_cloud.h>
#include <string>
class CloudSaver
{
public:
CloudSaver();
void saveCloudToPNG(const std::string & fileName, const pcl::PointCloud<pcl::PointXYZRGBNormal>& cl );
};
#endif // CLOUDSAVER_H
cloudsaver.cpp
#include "cloudsaver.h"
# include <pcl/io/png_io.h>
CloudSaver::CloudSaver()
{
}
void CloudSaver::saveCloudToPNG(const std::string & fileName, const pcl::PointCloud<pcl::PointXYZRGBNormal>& cl )
{
pcl::io::savePNGFile<pcl::PointXYZRGBNormal>(fileName, cl );
}
But I'm still curious, how to do it properly.
As far as I know, There are some issues related to png_io.h.
I have change the definition of PCL_DEPRECATED in png_io.h file with this definition,and every thing becomes OK.
template <typename T>
PCL_DEPRECATED (void savePNGFile (const std::string& file_name, const pcl::PointCloud<T>& cloud),
"pcl::io::savePNGFile<typename T> (file_name, cloud) is deprecated, please use a new generic "
"function pcl::io::savePNGFile (file_name, cloud, field_name) with \"rgb\" as the field name."
);
look at this link [https://github.com/PointCloudLibrary/pcl/pull/300]
I guess you are using the static version of PCL.
To solve this issue you need to declare those methods as inline.
For example, for PCL 1.7.1, you need to edit this file:
pcl-pcl-1.7.1/io/include/pcl/io/png_io.h
And on these lines, add the keyword inline:
85: inline saveRgbPNGFile(...
96: inline savePNGFile(...
107: inline savePNGFile(...
119: inline savePNGFile(...
173: inline savePNGFile(...
Now rebuild the library, and you should be able to compile without any issues.

Error: forming pointer to reference type 'const std::pair<double, unsigned int>&'.... I can't understand this error

I'm getting some errors when trying to use -> in an iterator type. When I dig in the library defining the iterator, it seems to me that everyhing is allright and that there is no reason for the error. Here is the code, part of boost::multi_array:
template <class T>
struct operator_arrow_proxy
{
operator_arrow_proxy(T const& px) : value_(px) {}
T* operator->() const { return &value_; }
// This function is needed for MWCW and BCC, which won't call operator->
// again automatically per 13.3.1.2 para 8
operator T*() const { return &value_; }
mutable T value_;
};
which is instantiated with const std::pair<double, unsigned int>&; then the compiler complains about "forming pointer to reference type 'const std::pair<double, unsigned int>&'".Those are internal, library substantiations. For the record, here is what I have in my code:
typedef uint32_t object_indentifier_t;
typedef std::pair< double, object_identifier_t > object_tab_t;
typedef boost::multi_array< object_tab_t, 2 > index_t;
and here is the usage that provokes the trouble:
object_identifier const& center; // Actually a parameter
index_t::const_subarray<1>::type::const_iterator pos_iterator_left = std::lower_bound( ix[i].begin(), ix[i].end(), sk[i], comparer );
assert( pos_iterator_left -> second == center ); // <-- Error steams from here
Here's more error context:
/opt/boost_1_48_0/include/boost/multi_array/iterator.hpp: In instantiation of 'struct boost::detail::multi_array::operator_arrow_proxy<const std::pair<double, unsigned int>&>':
csrc/lsh_cpp/lsh.cpp|125 col 13| required from here
/opt/boost_1_48_0/include/boost/multi_array/iterator.hpp|40 col 10| error: forming pointer to reference type 'const std::pair<double, unsigned int>&'
/opt/boost_1_48_0/include/boost/multi_array/iterator.hpp|43 col 7| error: forming pointer to reference type 'const std::pair<double, unsigned int>&'
csrc/lsh_cpp/lsh.cpp: In member function 'lsh_cpp::neighbour_iterator_t lsh_cpp::lsh_t::pimpl_t::query(const object_identifier_t&) const':
csrc/lsh_cpp/lsh.cpp|125 col 13| error: result of 'operator->()' yields non-pointer result
NOTE: This class is part of boost::multi_array, (I already wrote that), and I'm not instantiating it directly. I wrote above my instantiation. The class is instantiated by boost::multi_array this way:
operator_arrow_proxy<reference>
operator->() const
{
return operator_arrow_proxy<reference>(this->dereference());
}
The use of "reference" makes me think that the reference is intended. Is there a reason for taking address to a reference to not work? I think to remember having done it myself a couple of times, and getting the address of the original, aliased variable that way....
Taking address of a reference is not a problem, but it returns pointer to the underlying type, not pointer to reference. Pointers to reference can't be created nor would they make sense since references cannot be rebound. Declaring a pointer to reference type is an error.
The return type T * therefore won't work if T is a reference type. Similarly declaring a mutable T makes no sense if T is a reference type, because references cannot be rebound. So the operator_arrow_proxy is apparently written to expect a non-reference.
If boost instantiates it with reference member of anything, which is always a reference type, it looks like a bug. Indeed, appears to be reported as bug #6554.

force call to QString(const char *) constructor in Qt 4.7

I am trying to compile a library written in Qt 4.6. On my current Linux machine I have only Qt 4.7 installed. The following code part:
/*file try.h*/
void fileOpen(QString s = NULL) ;
/*file try.cpp*/
void MainWindow::fileOpen(QString s) {
QString filename ;
if(s.isNull()) filename = QFileDialog::getOpenFileName(
this,
"Choose a file",
".",
"Source file (*.)");
else filename = s ;
}
compiles with the following error (I used cmake but the corresponding line code is the one listed above):
In member function ‘virtual int MainWindow::qt_metacall(QMetaObject::Call, int,
void**)’:
/homes/combi/hodorog/Developments/axelOld/build/axel/src/QGui/moc_MainWindow.cxx:141:26:
error: conversion from ‘long int’ to ‘QString’ is ambiguous
/homes/combi/hodorog/Developments/axelOld/build/axel/src/QGui/moc_MainWindow.cxx:141:26:
note: candidates are:
/usr/include/QtCore/qstring.h:426:43: note: QString::QString(const char*)
/usr/include/QtCore/qstring.h:105:14: note: QString::QString(const QChar*)
So I am guessing the problem is that in qt. 4.7. there are two QString constructors that can take a pointer as an argument (as listed in the compilation error), whereas in qt 4.6. there is only one QString constructor that can take a pointer as an argument. How can I force QString to call the constructor with const char * as an argument?
Thank a lot for your help in advance,
madalina
void fileOpen(QString s = NULL);
You are trying to construct a QString object with 0. It seems you are confusing the null of pointers with a null QString. A null QString is one which is created with the constructor QString(). Given how your function is implemented (referring to s.isNull()), you should change the function declaration to
void fileOpen(QString s = QString());

Resources