Implementing your own property system (Qt-like) - c++

I want to implement my own simple property system (C++) similiar to one provided by Qt's Q_PROPERTY. The problem is that Qt's properties doesn't work from inside macros which I'm trying to use to add some additional functionality above properties. The aim is to be able to declare a property and automatically get access both through properties string name representation and regular methods:
MY_PROPERTY(QString, Name)
...
getObject()->setProperty("Name", "John");
...
myObject->setName("John");
QString name = myObject->getName();
I want to add all the needed functionality with a single line but the following code will not work, since MOC doesn't expand macros:
#define MY_PROPERTY(type, name)\
Q_PROPERTY(type name READ name WRITE change##name)\
\
void set##name(type param)\
{\
m_##name = param;\
DO SOMETHING
}\
Please advice any good books/articles on this topic.

most (>95%) condition, Qt Propery System is enough, if you really want to add something on yourself property when its setting or getting, you can use Qt signal/slot System to do this.
if you finally still want to do you own Property System, I think the best reference is Qt source code, isn't it?

Related

QT: Creating extension methods

EDIT: not currently possible, but being talked about in the C++ community.
*** I am new QT(C++) but have a C# background. Please forgive me, if this is not something done in QT.
I wanted to know if there is a way to create extension methods with QT(C++), much similar to what you can do C#?
Edit:
My objective is to reduce the nested function calls as they are. This is to avoid going to the trouble of creating a FilePath class, where the the QString method is overloaded to hide the formatting.
Here is an example of what I want to do.
I have a string that contains a system path. I use the QDir::fromNativeSeparatorsto escape the string for usage in the QFILE object.
Is there a way to create a static utilities class that would allow for the following?
QString Src = "E:/dfdf/dfdf/";
QFile file(Src.NativeSep());

Qt #define "signals" clashes with GStreamer (gst)

Qt, which seems to name everything else with an initial Q, does this: #define signals signals in qobjectdefs.h.
However, GStream, not naturally, does not imagine signals to be a reserved word and does this
struct _GDBusInterfaceInfo
{
/*< public >*/
volatile gint ref_count;
gchar *name;
GDBusMethodInfo **methods;
GDBusSignalInfo **signals; <==================
GDBusPropertyInfo **properties;
GDBusAnnotationInfo **annotations;
};
in gdbusintrospection.h.
Am I just to assume that Qt and GStreamer don't play well together., or is there a way around this?
Note: Qt can be persuaded to #define signals signals if I don't #define Q_MOC_RUN. But that leads to problems with classes which are using
class
{
public:
// stuff
signals:
// stuff
private:
// stuff
};
As you might have guessed by now, I am trying to take over code from someone who is not around to support it and Google is not my friend:-(
[Update] Thanks, #IpApp fro the tip (which is not working, alas).
I have been given someone else's code. Apparently it build for target, but has never been built for unit test and I have to do that (why he mix & matched, I do not know).
When I use QT_NO_KEYWORDS in Eclipse CDT, I get errors because the class definition code does not use Q_SINGAL(S) - it uses the signals macro (which is now defined as signals) to define certain public members.
I am not allowed to alter the subsytsem code, just to mock its interfaces, but I am loathe to mock all of Qt & Glib, because of the effort.
Perhaps there is a way to use libraries for one or the other, rather than including their directories into the source path?
Just follow this documentation in your qmake project file:
CONFIG += no_keywords
If you are using something else than qmake, make sure that you define the following in your buildsystem:
QT_NO_KEYWORDS
Then, you need to make sure that you use Q_SIGNALS or Q_SIGNAL all over the place in your headers so that moc (meta object compiler) is still notified that it is a signal.
I have found another solution which as for me is more convenient and simple - you should include glib headers before Qt headers, and thats all. As glib code goes before, it is unaffected by Qt define statements.

Cocoa: get path to Contents/Resources folder in cocoa bundle

I am aware of how to get a specific file from the Resources folder in cocoa, i.e. :
NSBundle* myBundle = [NSBundle mainBundle];
NSString* myImage = [myBundle pathForResource:#"Seagull" ofType:#"jpg"];
anyways, I'd like to have a simple function that gives me the path to the Resources folder so I can use it in c++ like this.
String getResourcePath()
{
return the correct path here
}
std::ofstream theFile;
theFile.open(getResourcePath()+"test.txt");
I guess I could manually combine the main bundle name with Contents/Resources, anyways I'd like to know if there is a more robust solution!
Thanks!
If you ever wonder if an Apple-provided class has a certain method, do look up Apple's own documentation before asking the question here at SO.
In this case, the answer is this method. But let me reiterate:
If you ever wonder if an Apple-provided class has a certain method, do look up Apple's own documentation before asking the question here at SO.
And, when you do so, go over all the methods in the documentation. That way, you'll learn what kind of methods are available.

Qt4.4 how to get the user settings path

linux: $HOME/.config
windows: %APPDATA%
mac os: $HOME/.config
It can be set using http://qt-project.org/doc/qt-4.8/qsettings.html#setPath, but it seems as I am not able to retrieve it.
http://qt-project.org/doc/qt-4.8/qlibraryinfo.html#location QLibraryInfo::LibrariesPath returns the system wide settings dir, which is not what I want.
Any ideas, or do I have to code it separately for each platform?
€: I want to create a sub directory, and store files into it. (You may punish me if this is a bad idea)
This might not answer your question directly: if you want to store per-user persistent data, shouldn't you use QDesktopServices::storageLocation(QDesktopServices::DataLocation) instead?
This is a nasty workaround. First you create QSettings, then get its location.
QSettings cfg(QSettings::IniFormat, QSettings::UserScope,
"organization", "application");
QString config_dir = QFileInfo(cfg.fileName()).absolutePath() + "/";
Credits go to the Qt Centre forum.
QSettings stores the default config in the user AppData directory. See documentation for QSettings. Also this code instructs to store the config in the Ini file format.
this works on both qt 4 and qt 5
QApplication::setApplicationName("MyApp");
QApplication::setOrganizationName("Me");
QString homePath;
#if QT_VERSION >= 0x050000
homePath = QStandardPaths::writableLocation(QStandardPaths::DataLocation);
#else
homePath = QDesktopServices::storageLocation(QDesktopServices::DataLocation);
#endif
Why do you need to know the settings path? If you are going to put settings in it, you could use QSettings. I could see making a subdirectory to hold various settings, but it seems like the easiest way would be to use QSettings directly.
As far as I can tell, you can't retrieve the path. In the Qt source, src/corelib/io/qsettings.cpp, there is a function to get the path:
static QString getPath(QSettings::Format format, QSettings::Scope scope)
{
...
but it's not accessible from code using Qt. You can't copy it and use it either, because it uses internal Qt globals to store the path...
EDIT: A solution was posted, using QDesktopServices.storageLocation(QDesktopServices.DataLocation) but it doesn't do exactly what the question was asking for, i.e. if I set a custom path using QSettings.setPath() it doesn't reflect the change.
What platform are you at?
Might be related or not but in windows, the default is to write QSettings to the registry.
I read more into the question than there was as it was originally posted. It is clearer after the edits. Ok, so can't you use..
QString QSettings::fileName () const
Returns the path where settings are written to using this QSettings object are stored.
On Windows, if the format is QSettings::NativeFormat, the return value is a system registry path, not a file path.

How to set text in Carbon textfield on OSX?

I'm trying to set the text of a textfield using the Carbon API like this:
ControlID editId = {'EDIT', 3};
ControlRef ctrl;
GetControlByID(GetWindowRef(), &editId, &ctrl);
CFStringRef title = CFSTR("Test");
OSErr er = SetControlData(ctrl, kControlEntireControl, kControlEditTextTextTag, CFStringGetLength(title), title);
CFRelease(title);
I'm using the C++ code template of XCode, so GetWindowRef() is a call to the predefined TWindow class. The OSErr return value gives me noErr, but my textfield only contains garbage.
It doesn't matter if I set the attribute of my textfield to Unicode or not.
Any ideas what is wrong here?
What does the GetControlID(...) return? Is it noErr?
As a ControlRef is also a HIViewRef, you can also use the function:
HIViewSetText to set the text. This is documented to work with functions that accept kControlEditTextCFStringTag.
By the way, the line you wrote:
CFRelease(title);
Will cause problems. One should only release objects that have been made using functions that have Create or Copy in the API name. You'll want to read: "Introduction to Memory Management Programming Guide for Core Foundation" -- search in the Xcode documentation.
Finally this did the trick:
SetControlData(ctrl, kControlEditTextPart, kControlStaticTextCFStringTag, sizeof(title), &title);
Since this seems to be very old API, a better way seems to be:
HIViewSetText(ctrl, title);
Thx to Lyndsey for the hints.