I'm trying to make a lua package using the Lua C API and LuaBridge, and I need to send data through a serial port, thus the use of Qt's QSerialPort.
The binding works fine, that is, I can use the class I registered with Lua in my scripts. However, every time I use QSerialPort::write, Qt prints tha following warning:
QObject::startTimer: Timers can only be used with threads started with QThread
I have not declared a QCoreApplication, and I do not know where I should declare it since a library doesn't have a main() function.
The closest thing I have to an entry point is
int luaopen_my_io_lib(lua_State *L);
which registers my class to Lua.
The QSerialPort is used as a member of the class I register, and constructed without a parent QObject.
How can I fix this?
[EDIT] here is the code that triggers the warning:
bool SerialIO::write(std::string data) {
m_port.write(data.c_str());
return m_port.waitForBytesWritten(100);
}
where m_port is a QSerialPort.
I think I should be able to fix it by starting a new QThread, but that would be a bit overkill for what I'm trying to achieve...
Related
A friend and I are working on a simple synthesizer in C++. We have working oscillator, filter and envelope classes and are able to output some sounds using Portaudio libraries.
We are now working on the graphic interface with Qt Creator but are quite confused with how to organise everything. Indeed, portaudio uses a callback function to fill the buffer and to do so, it needs to access the getValue() method of the ocsillator or the process() method of the filter. But at the moment, we declared our oscillator object and our filter object as pointers inside the MainWindow class. We thus cannot access their methods in the callback function.
More informations on the callback function of portaudio can be found here.
Here are 2 solutions that I thought of :
Putting all the synthesiser objects (osc, filter etc) as globals, so that I can access them in my callback function
Putting the callback function and all the sound-related functions in main.cpp instead of mainwindow.cpp and having the MainWindow object as global, so that I can access its attributes (i.e. the oscillator etc. objects) in the callback function.
I don't really know which solution is the best, or if there is any that would work better...
I am writing an application of middle size. I will have many gui components and many classes. However, it is difficult for me to organize the code, to separate the logic, ... For example, let say that I press one button that creates an object of a class and perform a computation on that object. After exiting the slot function of the button, this local object is destroyed. What if I need it in another function later? Defining everything as a global variable in the header file is not a good thing for me. So I was thinking of a static class that contains somehow pointers to all the objects I will need later. Does anybody has a better idea?
How to manage objects inside an application is always a tricky
question. Qt goes down a very object-oriented route and uses reference
semantics implemented through pointer for nearly everything. To
prevent tedious manual memory management Qt organizes everything into
Object Trees. This
is augmented by Qt own
object model that adds
some dynamic capabilities.
If you want to go down that route, stick to everything Qt provides. It
is much more similar to Java than the usual C++ approach and might be
more comforting for beginners and maybe suits your application
domain. It tightly ties your code to Qt and will make it hard to
separate from it.
One other approach means to simply forgo all Qt stuff and work out the
core logic of your application. Develop it in pure C++ and than have a
thin layer that ties this logic into your Qt application through
signals and slots. In such an approach you would opt to use more
value-semantics.
For your concrete example of creating an algorithm and keeping it
around. The Qt approach:
class MyAlgo : public QObject {
Q_OBJECT
public:
MyAlgo(QObject* o) : QObject(o) { }
virtual compute();
};
// use it in a mainwindow slot
void MainWindow::executeAlgorithm(const QString& name) {
MyAlgo* algo = this->findChild<MyAlgo*>(name);
if(!algo) {
// not found, create
algo = new MyAlgo(this); // make mainwindow the parent of this algo
algo->setName(name); // QObject name property
}
algo->compute();
}
first I must say that as a Python programmer, I might be seeing this problem from a wrong perspective, many years had passed since I wrote my last c++ code back in college.
I'm having a bit of a problem, trying to create a hybrid python/c++ plugin using firebreath. I've been succesfull so far integrating all the parts using boost/python.h, but a problem arose when I tried to fire an event from within python. I stumbled with the problem of having to bind together a python function with a c++ function (using the BOOST_PYTHON_MODULE). First I tried to bind directly python with my JSAPI derived class fbtestconpythonAPI, the problem with this approach seems to be the lack of reference to the JSAPI object instantiated by the browser, giving me all kinds of signature mismatch problems between python function and c++ equivalent at execution time.
The only thing that ocurred to me to fix this( I agree, is an ugly dirty solution), is to use a global pointer which I initialize by hand with set_pluginPointer. This actually works pretty well so far, but I know it is not the right way to do it. I read that I should not be using a "raw" pointer with a JSAPI object, but I'm not sure how to replace it with a shared_ptr for this particular implementation. Another problem is the global variable, wich is shared accross all instances, causing for example, that all events are fired on the last tab/window opened. One way to solve the latter would be creating some sort of array with an index being the current window/thread id, wich is something I should be able to access from both my JSAPI object and python/c++ function.
Of course I'm open, and will apreciate very much, any suggestions, on how to improve/fix either this particular workaround or, better, the correct way to communicate boost::python and firebreath without hacking.
Below is the relevant part of the plugin code
// Global pointer to plugin instance
fbtestconpythonAPI *fbtestPtr;
void fbtestconpythonAPI::set_pluginPointer(const std::string& val){
m_testString = val;
fbtestPtr = this; //Global pointer initialization
}
void echo(std::string x){
// Firing the echo event on the plugin instance using the global raw pointer
fbtestPtr->fire_echo(x, 1);
}
BOOST_PYTHON_MODULE(Pointless) {
def("echo", echo);
}
FB::variant fbtestconpythonAPI::echo(const FB::variant& msg){
int result_value;
Py_Initialize();
try {
initPointless(); // initialize Pointless
PyRun_SimpleString("import Pointless");
PyRun_SimpleString("Pointless.echo('hello world')");
object module(handle<>(borrowed(PyImport_AddModule("__main__"))));
object dictionary = module.attr("__dict__");
} catch (error_already_set) {
PyErr_Print();
}
Py_Finalize();
return 0;
}
From a quick look you'd setup your class for export like this:
class_<YourAPI, boost::noncopyable>("YourAPI", no_init)
.def("function", &YourAPI::function);
Then you can pass a reference to your C++ instance to Python, allowing you to call functions on it which in turn can fire events.
I am entering a realm that is new to me, but basically I need to implement callbacks in C++. I am designing a toolkit for myself to use to simplify my life. Basically it is a .dll plugin that will be exposing a lot of functions to my other .dll plugins.
One of these functions is HookEvent(const char *event_name, void *callback) which will allow me to hook different events that get fired. Here would be an example...
Example_Plugin1.dll does HookEvent("player_spawn", &Plugin1::Event_PlayerSpawn);
Example_Plugin2.dll does HookEvent("player_spawn", &Plugin2::Event_PlayerSpawn);
I need to figure out the best (and preferably easiest) method of setting up a callbacks system that will work well for this. I have been reading up on C++ callbacks for a few hours now, and found quite a few different approaches.
I assume the easiest thing to do would be make a template, and use typedef bool (ClassName::*EventHookCallback)(IGameEvent, bool); After that, I am a bit foggy.
I also read that Delegates or a .NET style events system are other possible approaches. I am already somewhat confused, so I don't want to confuse myself more, but figured it was worth asking.
Here is a link to the C++ .NET style events system I was reading about.
http://cratonica.wordpress.com/2010/02/19/implementing-c-net-events-in-c/
So what do you guys suggest? Any tips as far as implementing it would be most appreciated.
If you want generalized event firing Boost.Signals2 might be applicable.
The Boost.Signals2 library is an
implementation of a managed signals
and slots system. Signals represent
callbacks with multiple targets, and
are also called publishers or events
in similar systems. Signals are
connected to some set of slots, which
are callback receivers (also called
event targets or subscribers), which
are called when the signal is
"emitted."
Even if you don't need this level of flexibility you should be able to simplify the function binding in your code using Boost.Bind, or the C++0x equivalents.
EDIT:
There's an excellent discussion from Herb Sutter of the issues you could face here. You could use this for guidance if you decide you don't need the full Boost feature set, and so roll your own.
How about using Qt Signal and Slot? It does what callbacks do but without the messiness of making anything not part of your callback parameters global.
Boost.Signals would be my choice, combined with things like boost::bind and Boost.Function.
I would use an abstract base class as a plugin interface. (And in fact, I have used a pattern like the one below before.)
Library, PluginIfc.h:
class PluginIfc {
public:
virtual ~PluginIfc() = 0;
virtual bool EventCallback(const char* event_name, IGameEvent, bool) = 0;
};
// For Windows, add dllexport/dllimport magic to this declaration.
// This is the only symbol you will look up from the plugin and invoke.
extern "C" PluginIfc* GetPlugin();
Plugin:
#include <PluginIfc.h>
class Plugin1 : public PluginIfc {
public:
virtual bool EventCallback(const char* event_name, IGameEvent, bool);
Plugin1& get() { return the_plugin_obj; }
bool Event_PlayerSpawn(IGameEvent, bool);
// ...
private:
std::vector<std::string> _some_member;
static Plugin1 the_plugin_obj; // constructed when plugin loaded
};
Plugin1 Plugin1::the_plugin_obj;
PluginIfc* GetPlugin() { return &Plugin1::get(); }
This way, your plugin classes can easily have members, and C++'s virtual call mechanism takes care of giving you a good this pointer in EventCallback.
It may be tempting to make a virtual method per event type, say just make Event_PlayerSpawn and similar methods virtual. But then whenever you want to add an event type, if this means changing class PluginIfc, your old compiled plugins are no longer compatible. So it's safer to use a string event identifier (for extensibility) and have the main callback sort events off to more specific methods.
The major drawback here (as compared to a signal-slot type implementation) is that all callbacks must take the same set of arguments. But your question sounded like that would be adequate. And it's often possible to work within that limitation by making sure the set of arguments is very flexible, using strings to be parsed or Any-style objects.
Sounds like you might be interested in how to build your own plugin framework. The problems you'll encounter are likely the same. Have a look at this nice Dr Dobbs article Building Your Own Plugin Framework.
Hope this helps!
Implementing your own callback system is non-trivial.
My understanding is that your aim is to map event types to specific callback functions.
E.g. if "player_spawn" event is risen the &Plugin1::Event_PlayerSpawn will be called.
So what you should do is the following:
1) Define all the events of interest. Make them as generic as possible. They can
encapsulate any information you need
2) Create a Registrar. I.e. a class that all modules register their interest for specific
methods. E.g. Registrar.register(player_spawn,this,Event_PlayerSpawn);
3) Registrar has a queue of all subscribers.
4) You can also have a uniform interface for the modules. I.e. all module implement a specific function but based on event's data can do different things
5) When an event occurs, all the subscribers interested for the specific event get notified by calling the appropriate function
6)Subscriber can de-register when ever is need
Hope this helps.
According to the documentation the return value from a slot doesn't mean anything.
Yet in the generated moc code I see that if a slot returns a value this value is used for something. Any idea what does it do?
Here's an example of what I'm talking about. this is taken from code generated by moc. 'message' is a slot that doesn't return anything and 'selectPart' is declared as returning int.
case 7: message((*reinterpret_cast< const QString(*)>(_a[1])),(*reinterpret_cast< int(*)>(_a[2]))); break;
case 8: { int _r = selectPart((*reinterpret_cast< AppObject*(*)>(_a[1])),(*reinterpret_cast< int(*)>(_a[2])));
if (_a[0]) *reinterpret_cast< int*>(_a[0]) = _r; } break;
The return value is only useful if you want to call the slot as a normal member function:
class MyClass : public QObject {
Q_OBJECT
public:
MyClass(QObject* parent);
void Something();
public Q_SLOTS:
int Other();
};
void MyClass::Something() {
int res = this->Other();
...
}
Edit: It seems that's not the only way the return value can be used, the QMetaObject::invokeMethod method can be used to call a slot and get a return value. Although it seems like it's a bit more complicated to do.
Looking through the Qt source it seems that when a slot is called from QMetaObject::invokeMethod the return type can be specified and the return value obtained. (Have a look at invokeMethod in the Qt help)
I could not find many examples of this actually being used in the Qt source. One I found was
bool QAbstractItemDelegate::helpEvent
which is a slot with a return type and is called from
QAbstractItemView::viewportEvent
using invokeMethod.
I think that the return value for a slot is only available when the function is called directly (when it is a normal C++ function) or when using invokeMethod. I think this is really meant for internal Qt functions rather than for normal use in programs using Qt.
Edit:
For the sample case:
case 8: { int _r = selectPart((*reinterpret_cast< AppObject*(*)>(_a[1])), *reinterpret_cast< int(*)>(_a[2])));
if (_a[0]) *reinterpret_cast< int*>(_a[0]) = _r; } break;
the vector _a is a list of arguments that is passed to qt_metacall. This is passed by QMetaObject::invokeMethod. So the return value in the moc generated code is saved and passed back to the caller. So for normal signal-slot interactions the return value is not used for anything at all. However, the mechanism exists so that return values from slots can be accessed if the slot is called via invokeMethod.
It is Very useful when you deal with dynamic language such qtscript JavaScript QtPython and so on. With this language/bindings, you can use C++ QObject dinamically using the interface provided by MetaObject. As you probably know, just signals and slots are parsed by moc and generate MetaObject description. So if you are using a C++ QObject from a javascript binding, you will be able to call just slots and you will want the return value. Often Qt bindings for dynamic languages provides some facility to acces to normal method, but the process is definitely more triky.
All slots are exposed in QMetaObject, where the object can be accessed via a reflective interface.
For instance, QMetaObject::invokeMethod() takes a QGenericReturnArgument parameter. So I belive this is not for explicit slot usage, but rather for dynamic invocation of methods in general. (There are other ways to expose methods to QMetaObject than making them into slots.)
The invokeMethod function is, for example, used by various dynamic languages such as QML and Javascript to call methods of QObject:s. (There's also a Python-Qt bridge called PythonQt which uses this. Not to be confused with PyQt, which is a full wrapper.)
The return value is used when making syncrhonous calls across threads inside a Qt application (supported via invokeMethod and setting connection type to Qt::BlockingQueuedConnection, which has the following documentation:
Same as QueuedConnection, except the current thread blocks until the
slot returns.
This connection type should only be used where the emitter and receiver
are in
different threads. Note: Violating this rule can cause your application
to deadlock.