Unsolved Underlying compatibility issue with QObject names
-
I may be revisiting a question I asked before but I never really found an adequate answer. I am writing an object interface that needs to be able to access names of objects from different API's directly by using a type that they all have in common. Unfortunately there is a problem in doing this with QObjects since QObjects use QString which uses wide characters as its underlying type. Why does QObject do this? Qt is the only C++ API which I have come across that uses wide characters for its object names. I need to be able to access the name of a QObject without duplicating it. Here is my dillema:
class APPCORE_EXPORT BaseAppObject { ... public: virtual const char* appObjectName() const = 0; ... }; class APPCORE_EXPORT QtObject : public QObject, public BaseAppObject { Q_OBJECT };
Basically in the above QtObject class, I need to override the appObjectName method to directly access the Qt Object name so that it returns a const char pointer. Is there anyway to do this directly without a conversion? It appears the only way to do this currently is to create a temporary object that copies the name to a type that uses a const char* as its underlying string type (non-wide string). IMO this is a major shortcoming of the Qt object system because it makes it incompatible with naming conventions used in other C/C++ libraries.
If I must rebuild a custom version of of Qt, how widespread of a problem would it be to use a non-wide object name?
-
Why does QObject do this?
For consistency mostly and to avoid conversions within the library interface. There's too much string types in the world already. I don't think anyone would want Qt to use two different types for strings.
It appears the only way to do this currently is to create a temporary object that copies the name to a type that uses a const char* as its underlying string type
Well yeah, but just as long as you actually return that new type and not a
const char*
pointing to its data, as on the callers side this would be pointing to garbage.If I must rebuild a custom version of of Qt, how widespread of a problem would it be to use a non-wide object name?
For all intents and purposes this is a no-go. Basically rewriting entire QString, QByteArray, QStringRef, couple of other classes and doing tons of conversions all over the place inside Qt. This is a bad idea.
IMO this is a major shortcoming of the Qt object system because it makes it incompatible with naming conventions used in other C/C++ libraries.
Qt aims to cover a lot of ground when implementing apps and it's usually possible to a large degree to write code staying in Qt's API. The conversions are really needed only on the boundary of APIs, which you should strive to minimize anyway. To pass Latin1 strings into Qt you can take a look at QLatin1String. The other way around a conversion will be needed.
Bare in mind that Qt established QString back i the days of the strings wild wild west. The only justifiable way to say it's a bad design is by blaming the lack of future predicting psychic powers.
Besides, on Windows at least QString being a 16bit type is pretty convenient, as it allows for integrating it with WinAPI without conversions. Other platforms not so much, but hey, you can't make everyone happy. -
While it is true that Qt covers a lot of ground one ground it does not cover is graphics engines. It allows use of OpenGL but OpenGL is not in and of itself a graphics engine. My application needs to implement and expand a graphics engine AND host a scripting language interface that allows access to objects both in Qt and the graphics engine. This is why I need an object interface and an object manager that can access object names through a single function from both libraries. I am currently using the Irrlicht engine though I have entertained the idea of OGRE as well. Both of these use string types that allow me to access a const char* to get at the their data while Qt does not. So basically what you are saying is that I will need to duplicate string data in order to access Qt objects by name.
-
So basically what you are saying is that I will need to duplicate string data in order to access Qt objects by name.
Not necessarily. You can just not use the built in QObject
objectName
property and provide your own with whatever type you like e.g.class MyQObjectSubclass : public QObject { Q_OBJECT Q_PROPERTY(QLatin1String Name READ name WRITE setName NOTIFY nameChanged) public: inline QLatin1String name() const { return name_; } signals: void nameChanged() const; public slots: inline void setName(const QLatin1String& name) { name_ = name; nameChanged(); } private: QLatin1String name_; };
-
Well that kind of defeats the purpose and is effectively what I just said I would need to do. The purpose is to use the objectName property without wasting extra memory with duplicate string data.
-
Sorry but I don't follow. There's nothing duplicated in the code I gave. You can use
name().data()
to pass it intoconst char*
expecting APIs. There's no duplication or conversion here. -
Isn't there already a name for the object? objectName() already contains data (a QString). So creating another "name" variable means that there are two strings where I only want one. Unless you are replacing the objectName string. Basically that means there are two different variables that will contain the same string. One in char format and one in wide char format.
-
There is a QString property called objectName, but no one is forcing you to use it. Just leave it empty. Unused string has a size of a single pointer so it's not a big deal. Just use another property in the format you want like i proposed.
-
@primem0ver said in Underlying compatibility issue with QObject names:
While it is true that Qt covers a lot of ground one ground it does not cover is graphics engines.
The Qt3D module would beg to differ.
I have entertained the idea of OGRE as well.
The good thing about OGRE is that it's opensource and there it ends. The API is badly designed and the examples are outdated. To top that the documentation is ... pretty thin.
-
This post is deleted! -
@kshegunov
Hmm... well if it performs anything like your 2d graphics engine I want nothing to do with it. Honestly, it looks fairly meager compared to Irrlicht anyway which is what I plan on using. There also doesn't seem to be any built in scene UI support either which is an absolute must. I agree that Ogre 3D made some weird design choices which is why I eventually decided on Irrlicht. -
Hi
Just as a note. Did you ever test unreal engine ?
https://www.unrealengine.com/what-is-unreal-engine-4 -
@primem0ver said in Underlying compatibility issue with QObject names:
Hmm... well if it performs anything like your 2d graphics engine I want nothing to do with it.
I don't have a 2D graphics engine, so I have no idea what you're talking about.
Honestly, it looks fairly meager compared to Irrlicht anyway which is what I plan on using. There also doesn't seem to be any built in scene UI support either which is an absolute must.
If you mean Qt3D, there's no scene at all, the scene is defined by the root entity.
-
"Your..." as in Qt's 2D graphics engine. I am talking about the QGraphicsView. That is essentially a 2D graphics engine and it is horrendously slow.
Scene... um... the scene is the collection of objects that is rendered. That is a basic 3D concept. Some 3D API's have scene managers but regardless; the basic issue is that Qt3D doesn't seem to have built in support for 2D widgets/HUD controls for a scene which are a very important aspect of the application I am building.
I looked into a bunch of 3D engines before deciding on Irrlicht. I don't remember much about the difference between Unreal and Unity but I decided they were both not really useful in my project. I need a very portable, very source code oriented and expandable engine. I am not building a game and the user interface for the application is not meant to be created by the engine (though 2D user controls are a big part of what I need). On the contrary, the 3D engine is supposed to be hosted inside a control (widget in qt terminology). There are some other things I need that don't appear easy to do in the engine because it is too high level. Procedural meshes are a very large part of the graphics engine I need to develop.