Why Qt c files just have header inclusion and no implementaion code? - qt

I wanted to look into the implementation of QString. But when I opened the QString.c file then all I can see was header inclusion of qstring.h. So where is the actual implementation?

Qt creates a bunch of include files like the one you mention, its only purpose is to let the developer include using that syntax sugar, ie:
#include <QString>
#include <QWidget>
#include <QObject>
The 'real' header files are in another 'reachable' directory in the form you metion (qstring.h), so you can also do this:
#include <qstring.h>
#include <qwidget.h>
#include <qobject.h>
So the first kind includes the second one. The actual directory depends on your distribution/installation, in my case the second ones ('real' content) are at '/usr/include/Qt'.
Of course this is only the header file where all declarations are, if you mean by implementation the definition of the content, that will be somewhere in the source code (in .cpp files), and it's location depends on the particular module.

Related

Simple QThread example won't link properly

I want to use QThreadSynchronizer in my class, like so
#ifndef _MULTIWATCHER
#define _MULTIWATCHER
#include <QThread>
#include <QFutureSynchronizer>
#include "globals.h"
class MultiWatcher : public QThread
{
Q_OBJECT
public:
signals:
void allDone();
public:
void run() override;
QFutureSynchronizer<FocusResult> _sync;
};
#endif
However, when I try to build this I get the following linking errors
1>C:\Qt\5.7\msvc2015_64\include\QtCore/qvector.h(134): error C2182: 'at':
illegal use of type 'void'
1>C:\Qt\5.7\msvc2015_64\include\QtCore/qvector.h(135): error C2182: '[]':
illegal use of type 'void'
1>C:\Qt\5.7\msvc2015_64\include\QtCore/qvector.h(136): error C2182: '[]':
illegal use of type 'void'
etc ...
Actually I get the same errors if I comment out the entire class (its also the same if QThreadSynchronizer is replaced by QFuture) and just try to include the two include files, as if QThread and QFuture/QThreadSynchronizer are incompatible with each other. So the following also doesn't link!
#ifndef _MULTIWATCHER
#define _MULTIWATCHER
#include <QThread>
#include <QFuture>
#endif
Any ideas?
The problem was solved by changing the "Common Language RunTime Support" option from "Common Language RunTime Support /clr" to "No Common Language RunTime Support" for the moc_multiwatcher.cpp file that QT generates. These files are in "Generated Files"->Debug section of the Solution Browser, the clr setting for this file can be accessed by right clicking on it and going to properties. I hope this is useful for other people having strange linking errors in their c++/clr/QT visual studio projects.

Preprocessor makes function name unaccessabel

I have to create a SQLite database using System.Data.SQLite and using C++/CLI but I run into problems. Unfortunately, using C# is not an option, if it was then there is no problem. (Please don't advise me not to use C++/CLI, it is not an option in this project.)
In C# the following code works without any problem.
using System.Data.SQLite;
void CreateDb(String file)
{
SQLiteConnection.CreateFile(file);
}
The equivalent code in C++/CLI is not without its problems.
using namespace System::Data::SQLite;
void CreateDb(System::String ^file)
{
SQLiteConnection::CreateFile(file); // error C2039
}
The exact error txt for C2039 is:
// error C2039: 'CreateFileA' : is not a member of 'System::Data::SQLite::SQLiteConnection'
If I take a closer look at the definition of CreateFile I get the following choice
#define CreateFile CreateFileW - c:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Include\WinBase.h(9292)
#define CreateFile CreateFileA - c:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Include\WinBase.h(9294)
Which leads to the following lines in WinBase.h
#ifdef UNICODE
#define CreateFile CreateFileW
#else
#define CreateFile CreateFileA
#endif // !UNICODE
The Microsoft SDK is muddling with exact the name that I need and SQLite does not provide me with CreateFile[AW] versions.
So I tried this before the code calling SQLiteConnection.CreateFile(file) and I do this isolated so that other code is affected by it.
#ifdef CreateFile
#undef CreateFile
#endif
It solves my problem (for now) but how safe is this?
Is there a better way of solving this problem?
Your advise is much appreciated.
The #undef is how I've always handled this.
how safe is this?
This is safe.
You may have this problem again if you have other name collisions. The compile errors resulting from such a name collision are easy to diagnose, now that you know what you're looking for, so it will be easy to add additional #undef directives if needed.
If you need to call the Win32 CreateFile, you will need to type CreateFileA or CreateFileW explicitly, but that's not a big hassle.
Is there a better way of solving this problem?
Yes, but it's not always possible.
The better way is to not #include <Windows.h> in the files where you use SQLite. This avoids the problem entirely. However, it's not always possible to organize your program like this, so #undef is usually the solution.
(This next paragraph doesn't apply to your scenario with SQLite: You're using the managed version, so there's no headers. This next bit applies to C++ libraries that include library headers. I'm including it for completeness in case someone is writing plain C++.)
One other thing to watch out for here is #include-ing the Windows headers before library headers. In that case, the class definition itself will have CreateFile renamed to CreateFileA. If you use #undef with that, you'll get the opposite error from what you showed. You can leave the #define in place, which will sometimes end up working, but this is rather fragile, so I would avoid this scenario.
(I ran into this once with MFC headers in a C++ application: The changed method name ended up everywhere, even Intellisense showed the name as ending in "A". It worked anyway because the vTable was initialized inside the MFC DLL, and so all that mattered in the calling application was that the vTable pointed at the right method, which it was.)

What preprocessor can I used to detect if QT is used to build my codes

I am writing a library project in C, which may be built with or without QT. Is there any preprocessor directive (no extra headers are required) that can I use to distinguish whether QT is in use in the C code?
I would like to do somthing like:
#ifdef I_AM_QT
// some qt specific codes
#else
// some codes for other environments
#endif
Thanks.
#ifdef QT_CORE_LIB
// some qt specific codes
#else
// some codes for other environments
#endif

Variables in c++ builder XE2 not initializing when unit was called by component

I have a unit (WebFunctions.h) with the declaration
String RawURLAllowedChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ~.-_";
This unit works well in the app. But when I add a component which also declares WebFunctions.h, the initialization of RawURLAllowedChars does not occurs (RawURLAllowedChars = NULL).
To get the app back to work, plus remove the class declaration of the component is still necessary delete the WebFunctions.obj file.
Note: Any declarations in .cpp file, with or without a extern declaration in .h file, also are not working.
This is a bug in XE2 or I'm missing something? Thanks.
Obs.: Var declarations inside #ifndef .. #endif
Do not initialize a global variable in a header file. Declare the variable as extern in the .h file and then initialize it in the corresponding .cpp file, eg:
WebFunctions.h:
extern const String RawURLAllowedChars;
WebFunctions.cpp:
const String RawURLAllowedChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ~.-_";
This is more a workaround than a real solution... but...
Comment (in the .cpp file of main app) the line with #pragma link "Component", added with the component which uses WebFunctions.h (not initializing unit).
Delete all building files in Debug\Win32 folder.
Recompile the App.

Qt GUI Dialog Initialization Confusion

I am learning GUI coding with Qt and hope to clear up some confusion on my part. When I create a dialog with Qt Creator it creates code for me like this...
#ifndef LISTDIALOG_H
#define LISTDIALOG_H
#include <QDialog>
#include "ui_listdialog.h" //Q1:Why was this auto paced in cpp file instead of h file?
//Q2: This is what I'm really confused about.
//Is Ui namespace wrapping ui_listdialog class or the ListDialog class?
namespace Ui {
class ListDialog;
}
class ListDialog : public QDialog
{
Q_OBJECT
public:
explicit ListDialog(QWidget *parent = 0); //Q3: Why is this constructor explicit?
~ListDialog();
//CUSTOM FUNCTIONALITY NOT ADDED BY CREATOR (IGNORE FOR MY POST)
private slots:
void addItem();
void editItem();
void deleteItem();
//END CUSTOM FUNCTIONALITY
private:
Ui::ListDialog *ui; //Placed on heap instead of stack.
};
#endif // LISTDIALOG_H
There are things in the above code that differ from my 3 Qt books (all 3 out of date and ignore Creator).
My main confusion comes from Q2. Is "Ui" wrapping "ui_listdialog.h" or the class I have posted here ( class ListDialog )? The syntax seems to imply to me that it is wrapping the latter but I feel it must be actually wrapping the ui_listdialog.h class instead. Very confused about this. Can someone explain this clearly?
I also don't understand why the constructor was made explicit by Creator. I have not seen that in any of the 3 books.
Q1. The #include is placed in the .cpp to avoid too many dependencies in the header file. This shortens compilation time, because if you change the dialog, the only thing you have to recompile is the .cpp and not everything that includes your header file. In general, if a forward declaration of a class is enough (i.e. you only have a pointer or a reference to it in your class), then it's better not to #include the class's definition.
Q2. Ui is a namespace that contains a different class called ListDialog. You can open the header file and see the definition of this other class. A bit confusing until you get used to it.
Q3. It's a good habit to use the explicit keyword with constructors that take a single parameter. Otherwise the constructor can also be used as an automatic conversion operator, and this can cause problems if you're not aware of it. For example, if you have a function that takes a ListDialog parameter, and you pass a QWidget * parameter, it may call the constructor when in fact you want the compiler to shout (invalid parameter).
The ui_listdialog.h contains implementation to generate your user interface based on Qt Designer. It isn't necessary when declaring the class -- that's why the file was #included in the .cpp (Q1). Without the ui_listdialog.h in the header, the class declaration is necessary (Q2).
As for Q3, it's probably there to make you use the constructor syntax. Else, you could write misleading statements like
ListDialog dialog = parentDialog ;

Resources