I'm developing a bunch of Qt applications in C++ and they all use some modules (translation units) for common functionality that use Qt as well.
Whenever I convert a C string (implicit conversion) or C++ string object (fromStdString()) to a QString object, I expect the original data to be UTF-8 encoded and vice versa (toStdString()).
Since the default is Latin-1, I have to set the codec "manually" (in the init procedure of every one of my programs) to UTF-8:
QTextCodec::setCodecForCStrings(QTextCodec::codecForName("utf8"));
Not all of my modules have an init procedure. The ones containing a class do (I can put this line in the class constructor), but some modules just contain a namespace with lots of functions. So there's no place for setCodecForCStrings(). Whenever I convert from/to a QString implicitly (from within one of my modules), I rely on the codec being already set by the init procedure of the main program, which seems to be a rather bad solution.
Is there a reliable way to set the codec to UTF-8 in my modules, or will I just have to be very careful not to use implicit conversions at all (in my modules at least) and write something like std::string(q.toUtf8().constData()) instead of q.toStdString()?
This can be done using a class definition for an automatically instantiated singleton-similar class having some init code in its constructor:
class ModuleInit {
static ModuleInit *instance;
public:
ModuleInit() {
QTextCodec::setCodecForCStrings(QTextCodec::codecForName("utf8"));
}
};
ModuleInit * ModuleInit::instance = new ModuleInit(); // put this line in .cpp!
Putting this code anywhere into any project will set the text codec to UTF-8. You can, however, overwrite the text codec in the main() method, since the code above is executed even before the main() method.
With "anywhere" I of course mean places where it is syntactically allowed to. Put the class definition in some header file, and the instantiation in the appropriate .cpp file.
You can even put the whole code in one .cpp file, say moduleinit.cpp which you compile and link, but never explicitly use (there is no header file you could include...). This will also avoid accidental instantiations except the very first one and you will not have any problems with duplicate class names.
Note that you can't set the codec for C-strings in one particular file. Setting the codec using QTextCodec::setCodecForCString will set it application-wide!
Related
How do I define a single context in a QtLinguist .ts file, rather than having one context per file?
I need this because I have identical strings showing up in different files for which I want the same translation (and no duplicates)
From C++, you can explicitly specify the translation context on a string-by-string basis by using the static function QCoreApplication::translate(const char* context, const char* text) instead of the traditional QObject::tr(const char* text) (see this doc for more details: http://doc.qt.io/qt-5/qcoreapplication.html#translate)
e.g.
menuItem->setText(QCoreApplication::translate("UniversalContext", "Exit"));
Similarly, you can specify the context in QML using the qsTranslate(context, text) function, a la
Text { text: qsTranslate("UniversalContext", "hello") }
These will all get picked up by lupdate as belonging to the same context (duplicate strings will only show up once in your .ts file)
If you have a lot of strings and it gets painful to specify the context on every call to translate/qsTranslate, you should be fairly simple to create a 1-arg macro (c++) or a js function (qml) as a wrapper.
I need to continue writing to the same file using a file output stream, However I'm implementing the program using a javafx GUI from different windows. but:
Since you can not access a global variable without intializing the stream as final I have to make it final however,
Since I have to wrap the the Stream in a try catch, the variable is not recognised as initialised.
I was previously intialising in method like this
eW = outputFactory .createXMLEventWriter(new FileOutputStream("File.txt"));
However, that obivously overwrites the same file when you write the same statement again.
So essentially my question is, how can you set a final variable that needs to be surrounded in a try catch?
final File file = new File("File.txt");
final FileOutputStream fileOS = new FileOutputStream(file);
You don't need to initialize a variable as final to access it from different threads or objects. There are other ways to do it.
You can use a helper class, or even a helper thread. The second option is better in (the most common) case where you have more than 1 thread in your project. You can then use a normal try-catch block that has a (almost infinite) while loop inside, that checks a write queue and writes something when needed.
If you only use 1 thread and only append to a file, you may want to do just that - open the file to append, rather than overwrite. There's a boolean flag in the constructor.
You can take a look at the FileOutputStream(File file, boolean append) constructor, which would allow you to append to the end of the file rather than overwrite each time.
I do not know how you implemented it, but if you are writing to the same file from multiple windows, it might be easier to have a helper class which exclusively handles writing to file. This would allow you to centralize your File output code to one place making it easier to debug and maintain.
Similar questions have been raised multiple times, but I'm focussing on the namespace and pointer issues.
MyClass.h
namespace foo {
class MyClass {
MyClass();
};
QDataStream &operator<<(QDataStream &out, const MyClass & myObj);
QDataStream &operator>>(QDataStream &in, MyClass &myObj);
} // namespace foo
Q_DECLARE_METATYPE(foo::MyClass) // #1
Q_DECLARE_METATYPE(foo::MyClass*) // #2
fooMyClass.cpp (so many permutations):
MyClass::MyClass()
{
qRegisterMetaType<MyClass>("MyClass"); // #3
qRegisterMetaType<MyClass*>("MyClass*"); // #4
qRegisterMetaType<MyClass>("foo::MyClass"); // #5
qRegisterMetaType<MyClass*>("foo::MyClass*"); // #6
qRegisterMetaType<foo::MyClass>("foo::MyClass"); // #7
qRegisterMetaType<foo::MyClass*>("foo::MyClass*"); // #8
qRegisterMetaType<MyClass>(); // #9
qRegisterMetaType<MyClass*>(); // #10
qRegisterMetaType<foo::MyClass>(); // #11
qRegisterMetaType<foo::MyClass*>(); // #12
// same for qRegisterMetaTypeStreamOperators<T>();
}
So my question is, when and why is it required to provide the namespace and/or the pointer variant if I intend to use the custom objects for signals and slots (potentially as reference and pointer) inside as well as outside the namespace. Do I always have to fully qualify the namespace?
I'm referring to Qt5 in this answer. Qt4 doesn't go well with this use case.
Data stream operators
Data stream operators are not required for your type if you only intend to use it in signals and slots. They are required if you want to do some serialization.
Pointers, references and values
Qt considers MyClass and MyClass* two different unrelated types. You should declare, register and use them separately. Using const MyClass & argument type is compatible with MyClass in Qt meta-object system. Note that using MyClass and MyClass* meta types simultaneously in one program is unusual and can cause mistakes and confusion. You should choose one of the options and use it throughout the program. Also passing pointers to slots is not recommended because it causes unsolvable ownership problem. So I recommend to use passing by const reference (which sometimes will be converted to passing by value internally in Qt signal-slot system). If MyClass objects contain massive data, you should implement implicit data sharing using QSharedDataPointer.
Declaring a meta type
First of all, you always need to declare your meta type:
Q_DECLARE_METATYPE(foo::MyClass)
It works at compile time, so there are no limitations on how you refer to your class. The following code will work as well:
using namespace foo;
Q_DECLARE_METATYPE(MyClass)
Registering a meta type
Now you need to register your classes. Theoretically, you need to specify all strings that you want to use to refer to your type, i.e.:
qRegisterMetaType<foo::MyClass>("MyClass");
qRegisterMetaType<foo::MyClass>("foo::MyClass");
It doesn't matter how you refer to MyClass in the template argument. The following code will work similarly:
using namespace foo;
qRegisterMetaType<MyClass>("MyClass");
qRegisterMetaType<MyClass>("foo::MyClass");
For example, the "MyClass" and "foo::MyClass" strings are used to identify argument types when you refer to your signals and slots like SIGNAL(signal1(MyClass)).
New signal and slot syntax
If you using new signal slot syntax with pointers to member functions, you need to do only one registration with arbitrary string argument. It seems that it is intended to make it work even without any registrations. This part of the docs instructs to only add Q_DECLARE_METATYPE, in opposite to this that requires qRegisterMetaType(). Unfortunately, now in my Qt installation it works only with direct connections. Queued connections still require at least one registration call.
Implicit registration of class without namespace
I was experimenting with some variants of registration in Qt 5.1 and found out that Qt automatically registers aliases without namespace. So if you write
qRegisterMetaType<foo::MyClass>("foo::MyClass");
, Qt will additionally automatically register "MyClass" alias. So, after executing this statement you will be able to refer to your type as MyClass and foo::MyClass. There is no information in the documentation about how Qt handles namespaces. We could assume that this behavior is intended and will not be removed in next versions but I wouldn't rely on that. The following code makes implicit registration obvious:
qRegisterMetaType<foo::MyClass>("foo::MyClass");
qRegisterMetaType<bar::MyClass>("MyClass");
Qt 5.1 says:
QMetaType::registerTypedef: Binary compatibility break -- Type name 'MyClass' previously registered as typedef of 'MyClass' [1030], now registering as typedef of 'bar::MyClass' [1032].
Qt 4.8 works without error (it seems that this behavior is not yet introduced in this version).
I need to change to reference of a function in a mach-o binary to a custom function defined in my own dylib. The process I am now following is,
Replacing references to older functions to the new one. e.g _fopen to _mopen using sed.
I open the mach-o binary in MachOView to find the address of the entities I want to change. I then manually change the information in the binary using a hex editor.
Is there a way I can automate this process i.e write a program to read the symbols, and dynamic loading info and then change them in the executable. I was looking at the mach-o header files at /usr/include/mach-o but am not entire sure how to use them to get this information. Do there exist any libraries present - C or python which help do the same?
interesting question, I am trying to do something similar to static lib; see if this helps
varrunr - you can easily achieve most if not all of the functionality using DYLD's interposition. You create your own library, and declare your interposing functions, like so
// This is the expected interpose structure
typedef struct interpose_s {
void *new_func;
void *orig_func;
} interpose_t;
static const interpose_t interposing_functions[] \
__attribute__ ((section("__DATA, __interpose"))) = {
{ (void *)my_open, (void *) open }
};
.. and you just implement your open. In the interposing functions all references to the original will work - which makes this ideal for wrappers. And, you can insert your dylib forcefully using DYLD_INSERT_LIBRARIES (same principle as LD_PRELOAD on Linux).
Can someone explain to me the basic idea of Qt signals&slots mechanism IMPLEMENTATION?
I want to know what all those Q_OBJECT macros do "in plain C++".
This question is NOT about signals&slots usage.
added:
I know that Qt uses moc compiler to transform Qt-C++ in plain C++.
But what does moc do?
I tried to read "moc_filename.cpp" files but I have no idea what can something like this mean
void *Widget::qt_metacast(const char *_clname)
{
if (!_clname) return 0;
if (!strcmp(_clname, qt_meta_stringdata_Widget))
return static_cast<void*>(const_cast< Widget*>(this));
return QDialog::qt_metacast(_clname);
}
Concerning the signals and slots, the Q_OBJECT macro adds a virtual function qt_metacall() declaration into the class’s declaration which is to be defined later by the the moc. (It also adds some declarations for conversion but that’s not too important here.)
The moc then reads the header file and when it sees the macro, it generates another .cpp file named moc_headerfilename.cpp with the definitions to the virtual functions and – you might have asked yourself why you can get away with mentioning the signals: in your header file without a proper definition – of the signals.
So, when a signal is called, the definition from the mocfile is executed and QMetaObject::activate() is called with the signal’s name and the signal’s arguments.
The activate() function then figures out which connections have been established and fetches the names for the appropriate slots.
Then it calls qt_metacall with the slot names and the arguments given to the signal and the metacall function delegates this with the help of a large switch—case statement to the real slots.
As there is no real runtime information possible in C++ concerning the actual names for the signals and slots, as has already been noticed, these will be encoded by the SIGNAL and SLOT macros to simple const char*s (with either "1" or "2" added to the name to distinguish signals from slots).
As is defined in qobjectdefs.h:
#define SLOT(a) "1"#a
#define SIGNAL(a) "2"#a
—
The other thing the Q_OBJECT macro does is defining the tr() functions inside your object which can be used to translate your application.
Edit
As you asked what the qt_metacast is doing. It checks whether an object belongs to certain class and if it does returns the pointer to it. If it doesn’t, it returns 0.
Widget* w = new Widget();
Q_ASSERT(w->qt_metacast("Widget") != 0);
Q_ASSERT(w->qt_metacast("QWidget") != 0);
Q_ASSERT(w->qt_metacast("QObject") != 0);
Q_ASSERT(w->qt_metacast("UnrelatedClass") == 0);
This is needed to provide some runtime reflection which is not possible otherwise. The function is called in QObject::inherits(const char *) for example and simply checks for inheritance.
Those macros do absolutely nothing "in plain C++", - they expand to empty strings (I think).
QT uses a meta-object compiler, that generates C++ code for Q_OBJECT-enabled classes (implementing the signals/slots you define, among other things).
You can read more about it in the official documentation.
The basic idea is that you can connect your objects allowing them to execute a method (slot) when a signal is done.
connect(pistol,SIGNAL(sigShoot()),runner,SLOT(slotRun()))
Doing the connection above, when the pistol emits the signal, the runner will execute its slot.
To do this, you have to declare your signals and slots in your respective classes.
Is the basic idea.
Good luck!