Referencing WebKit or WebEngine in .ui file depending on Qt version - c++

I am attempting to upgrade a Qt application from 5.3.1 to 5.7.0. The main change is the migration from WebKit to WebEngine.
http://doc.qt.io/qt-5/qtwebenginewidgets-qtwebkitportingguide.html
We are not yet ready to stop using 5.3.1, so I created a preprocessor define based on the Qt version. This works well for the project file, class source, and class header. However, I don't see a way to do this in the .ui file.
The Qt version is used to define a preprocessor define in the .pro file:
greaterThan(QT_MAJOR_VERSION, 4) {
QT += widgets
greaterThan(QT_MINOR_VERSION, 5) {
QT += webengine webenginewidgets
DEFINES += _WEBENGINE_
} else {
QT += webkit webkitwidgets
}
}
This works well in the .cpp file:
#ifdef _WEBENGINE_
#include <QWebEngineView>
#include <QWebEnginePage>
#include <QWebEngineFrame>
#include <QWebEngineElement>
#else
#include <QWebView>
#include <QWebPage>
#include <QWebFrame>
#include <QWebElement>
#endif // _WEBENGINE_
These are the offending references in the .ui file:
<widget class="QWebView" name="webView" native="true">
...
</widget>
...
<customwidget>
<class>QWebView</class>
<extends>QWidget</extends>
<header>QtWebKit/QWebView</header>
</customwidget>
Which results in the ui_*.h file:
#include <QtWebKitWidgets/QWebView>
...
public:
QWebView *webView;
How can I use the correct include paths and class names in the .ui file depending on the Qt version?

You cannot do that in the .ui file. The usual way to solve this would be by creating your own wrapper widget, and using that in the .ui file.
class MyWebView : public QWidget
{ .... }
MyWebView::MyWebView(QObject *parent) : QWidget(parent)
{
#ifdef _WEBENGINE_
// add webengineview to layout so it takes all space
#else
// add webview to layout so it takes all space
#endif
...
}

Related

The program has unexpectedly finished in QT opencv

I know that this has been posted many times,but I could not find the solution from previous posts. I followed tutorial on How to setup Qt and openCV on Windows from wiki Qt.
My .pro file and mainwindows.cpp are shown below. I wanted to open image following the example. What is wrong here? Checked the opencv version and it is the same as libs included. The PATH is also correct.
The cpp file
#include "ui_mainwindow.h"
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
cv::Mat image = cv::imread("C://1.jpg", 1);
cv::namedWindow("My Image");
cv::imshow("My Image", image);
}
MainWindow::~MainWindow()
{
delete ui;
}
and
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = opencvtest
TEMPLATE = app
DEFINES += QT_DEPRECATED_WARNINGS
SOURCES += main.cpp\
mainwindow.cpp
HEADERS += mainwindow.h
FORMS += mainwindow.ui
INCLUDEPATH += C:\opencv\build\include
LIBS += C:\opencv-build\bin\libopencv_core451.dll
LIBS += C:\opencv-build\bin\libopencv_highgui451.dll
LIBS += C:\opencv-build\bin\libopencv_imgcodecs451.dll
LIBS += C:\opencv-build\bin\libopencv_imgproc451.dll
LIBS += C:\opencv-build\bin\libopencv_features2d451.dll
LIBS += C:\opencv-build\bin\libopencv_calib3d451.dll
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
When program crashes like that under Qt Creator, and you have extra libraries, the very likely reason is that the extra libraries are missing from the runtime PATH.
In this case, you need to add C:\opencv-build\bin to the PATH. There are at least 3 ways to go about it.
Edit the system environment, so that the relevant directory is always in the system PATH. You need to restart Qt Creator for this change to take effect. This is not the recommended way, unless you actually want these things in there also for other purposes.
You can edit the Build environment of the project under Qt Creator Project view. There's separate configuration for each build type, so you may need to do this to them all separately, which both good and bad. It is good, because then you can have different directory for different builds (for example debug vs relase, MSVC vs MinGW builds). It's bad because it's extra hassle and makes it easier to have something wrong.
You can add it to the run environment in the Qt Creator Project view. Then it will be the same for all build types.
In this case, 3 is probably the way to go.
Qt Creator annoyingly does not display any information about which DLL is missing, it just says the program crashed. This can be solved by instead string the "Qt command prompt" for the correct toolchain from Windows Start menu (search Qt and you should find it). Then go to the built .exe directory and run the .exe. You should now get an error dialog where Windows tells you which DLL it failed to find. Then you can look where that DLL is and add it to the path and try again, until the program starts. After you know the directories using this method, you can then add them to Qt Creator as explained above.

Qt with WinRT C++ build issue

I want to build a modern Windows application using WinRT (Windows 10). I use Qt 5.13.1 UWP kits for Visual Studio 2017. When building a project, it displays a lot of compilation errors:
Code:
testproject.pro
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
CONFIG += c++17
# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \
main.cpp \
testproject.cpp
HEADERS += \
testproject.h
FORMS += \
testproject.ui
LIBS += -lwindowsapp
# Default rules for deployment.
#qnx: target.path = /tmp/$${TARGET}/bin
#else: unix:!android: target.path = /opt/$${TARGET}/bin
#!isEmpty(target.path): INSTALLS += target
testproject.h
#ifndef TESTPROJECT_H
#define TESTPROJECT_H
#include <QDialog>
#include <QDebug>
#include "winrt/Windows.System.Diagnostics.h"
using namespace winrt;
using namespace Windows::System::Diagnostics;
QT_BEGIN_NAMESPACE
namespace Ui { class TestProject; }
QT_END_NAMESPACE
class TestProject : public QDialog
{
Q_OBJECT
public:
TestProject(QWidget *parent = nullptr);
~TestProject();
private:
Ui::TestProject *ui;
};
#endif // TESTPROJECT_H
testproject.cpp
#include "testproject.h"
#include "ui_testproject.h"
TestProject::TestProject(QWidget *parent)
: QDialog(parent)
, ui(new Ui::TestProject)
{
ui->setupUi(this);
init_apartment();
auto info = SystemDiagnosticInfo::GetForCurrentSystem();
auto memory = info.MemoryUsage().GetReport().TotalPhysicalSizeInBytes();
qDebug() << memory;
}
TestProject::~TestProject()
{
delete ui;
}
Without WinRT code it compiles successfully. Any ideas how to configure WinRT using Qt? What libraries are required for Qt to run WinRT code? Thanks in advance.
Try either adding #undef X64 before #include "winrt/Windows.System.Diagnostics.h" or go to your project settings, select "Configuration Properties" -> "C/C++" -> "Preprocessor", in the dropdown next to "Preprocessor Definitions" select "Edit", remove the line X64. I've no idea what this define is for, but it conflicts with the ProcessorArchitecture::X64 enum in Windows.System.0.h.
PS. This answer is just a reproduced guesswork as I can't make much sense of the errors on the screenshot. Usually copy-pasting the text from the Output panel is more informative than the Error List.

How to get the CImg library working for Qt

I'm currently learning how to use Qt. I want to try out some simple image processing applications using Qt, and since I'm already familiar with CImg I want to use that. I guess it should be possible to do so, if not mark my question for deletion or something.
My question is: how to get CImg working for Qt? CImg is a header file. Lets say its located on my desktop. I import it using Qt creator 4.1.0, by using the "add existing file..." in the rightclick menu on the header folder. Then my menu looks like this:
.
It compiles when I add #include "CImg.h", but I can't use it, even when I'm trying to type using namespace cimg_library it will tell me that cimg_library doesn't exist. I also tried just creating a header file and copying the content of the CImg.h into it but then it simply fails to compile and the Qt Creator freezes.
Edit: I managed to make the situation a bit better by adding the header location to the include code (like this: #include "C:/Users/Marci/Desktop/CImg.h" )I can now "see" CImg related stuff in the dev environment, and it won't bother me with not finding the constructor for CImg or anything like that. However when I try to compile while using anything CImg related it will give me around 20 linker errors. (Error code: LNK2019) My .pro file looks like this:
#-------------------------------------------------
#
# Project created by QtCreator 2016-11-08T17:08:58
#
#-------------------------------------------------
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = grayscale
TEMPLATE = app
SOURCES += main.cpp\
mainwindow.cpp
HEADERS += mainwindow.h \
C:/Users/Marci/Desktop/CImg.h
LIBS += -C:/Users/Marci/Desktop/ -CImg.h
FORMS += mainwindow.ui
Edit2: after implementing the changes that PeterT suggested in his comment my .pro file looks like this:
#-------------------------------------------------
#
# Project created by QtCreator 2016-11-08T17:08:58
#
#-------------------------------------------------
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = grayscale
TEMPLATE = app
SOURCES += main.cpp\
mainwindow.cpp
HEADERS += mainwindow.h \
INCLUDEPATH += C:/Users/Marci/Desktop
FORMS += mainwindow.ui
And my mainwindow.cpp (in which i'm trying to create a CImg object) looks like this:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <CImg.h>
using namespace cimg_library;
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
CImg<unsigned char> myimage(100,200);
}
MainWindow::~MainWindow()
{
delete ui;
}
The compiler errors i get are: error: C2871: 'cimg_library': a namespace with this name does not exist
error: C2065: 'CImg': undeclared identifier
error: C2062: type 'unsigned char' unexpected
I hope this is specific enough.
After I few months I figured it out. The problem lies in the fact, that CImg uses a windows .dll file for the visualizing functions of the class cimg_display. Since Qt is platform independent it doesnt like this. However you can make it work with an interesting trick. First you need to include the header file normally, in the project file. After that, whenever you actually #include it, you need to write the following macro:
#define cimg_display 0
In my understanding this makes it work, because the C and C++ compilers simply copy the content of the included file into the source. And thanks to the macro the compiler will ignore the class thats causing trouble for us.

Simple Qt project with openCV instantly crash

I try to use openCV in a Qt project. But my release build instantly crash on launch if I link the release libs of openCV. Debug libs allow the programm to start but the application crashes when I try to use openCV functions (it is known that mixing release/debug in openCV causes some crash).
So I made a simple project and it won't even launch. Both release and debug build crashes and using debugger causes a small window saying 'unexpected CDB exit'.
Here are the source.
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = test_openCV
TEMPLATE = app
#flags to generate a .map file
QMAKE_LFLAGS_RELEASE +=/MAP
QMAKE_LFLAGS_RELEASE += /debug
SOURCES += main.cpp\
MainWindow.cpp
HEADERS += MainWindow.h
FORMS += MainWindow.ui
INCLUDEPATH += $$PWD
INCLUDEPATH += "D:/openCV/build/include"
#Switching between handbuild and the build I downloaded have no effect.
#I am sure the path are good. Quadra checked.
#LIBS += -L"D:/openCV/build/x64/vc11/lib"
LIBS += -L"D:/openCV/hand_build/lib/Release"
LIBS += -L"D:/openCV/hand_build/lib/Debug"
#disables the "fopen not secure" warning in openCV.
DEFINES += _CRT_SECURE_NO_WARNINGS
win32:CONFIG(release, debug|release): LIBS += -lopencv_core2413 -lopencv_highgui2413 -lopencv_imgproc2413
else:win32:CONFIG(debug, debug|release): LIBS += -lopencv_core2413d -lopencv_highgui2413d -lopencv_imgproc2413d
main.cpp:
#include "MainWindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
MainWindow.h:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <opencv/cv.h>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
and MainWindow.cpp:
#include "MainWindow.h"
#include "ui_MainWindow.h"
#include "opencv2/core.hpp"
#include "opencv2/highgui.hpp"
#include <QDebug>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
//Removing this line will causes the program to start normally (guess it won't link the libs if nothing from openCV is used).
cv::Mat image;
}
MainWindow::~MainWindow()
{
delete ui;
}
What I get when launching app:
Starting D:\Colin\build_test_openCV\release\test_openCV.exe...
program suddenly ended
D:\Colin\build_test_openCV\release\test_openCV.exe crashed
I work on Windows 7 / MSCV2012 openGL 64bits / Qt 5.2.1 openGL.
Does anyone see a mistakes I could have made?
I have a similar setup as yours and was getting the exact same problem. The issue was that the path to the corresponding dlls was not defined. These dlls:
opencv_core2411.dll
opencv_highgui2411.dll
opencv_imgproc2411.dll
should be in D:/openCV/hand_build/bin/ (or maybe D:/openCV/hand_build/bin/Release/). Adding another line:
LIBS += -L"D:/openCV/hand_build/bin/Release/"
should work.
I just had a similar issue. The program was crashing because it could not find the appropriate DLL at runtime. Adding the OpenCV directories to my Windows PATH fixed the problem for me.
All items in your build must have been built using the same Visual Studio version, that means:
The Qt install you're using.
OpenCV.
Your code.
Most likely at least one of the above was not built using the same compiler. If OpenCV is linked against Qt, it must have been built against a binary-compatible version of Qt, too.

QT/C++, OS X: Alternative for hide() when quiting app so that app keeps running and shows up again after clicking icon in dock

I'm using QT with c++ on Mac OS X.
When closing my application I use hide() to keep my app running and to hide the window.
But afterwards when I click on the icon of my app in the dock, it does not show up anymore.
I read here that using the following code instead of hide() should fix this behaviour:
ProcessSerialNumber pn;
GetFrontProcess (&pn);
ShowHideProcess(&pn,false);
But I don't know how to use that code :s
Can somebody explain how to use this code, or how to solve my problem?
thanks!
You can compile Objective-C inside your Qt app, so do the next:
Add this to your .pro file:
macx {
LIBS += -framework Foundation
LIBS += -framework AppKit
OBJECTIVE_SOURCES += objectivec.mm
HEADERS += objectivec.h
}
Create a file called objective.h:
#ifndef __ObjectiveC_h_
#define __ObjectiveC_h_
class ObjectiveC
{
public:
static void HideWindow();
};
#endif
Another one called objective.mm:
#include "objectivec.h"
#import <Foundation/Foundation.h>
#import <AppKit/AppKit.h>
#import <CoreData/CoreData.h>
void ObjectiveC::HideWindow()
{
[NSApp hide:nil];
}
And then just use this wherever you like:
#ifdef Q_OS_MAC
#include "objectivec.h"
#endif
#ifdef Q_OS_MAC
ObjectiveC *obc = new ObjectiveC();
obc->HideWindow();
#endif
The code you are talking about is native OSX API. I am in foreign territory but I am going to try to make magic here:
for ProcessSerialNumber
//either
#include <Carbon/Carbon.h>
#include <Cocoa/Cocoa.h>
for GetFrontProcess (&pn);
Documentation:
The GetFrontProcess function returns the process serial number of the process running in the foreground. Return "undef" if an error was detected.
Signature:
//carbon or cocoa
OSErr GetFrontProcess (ProcessSerialNumber *PSN);
for ShowHideProcess(&pn,false);
Signature:
#include <Carbon/Processes.h> //carbon only?
OSErr ShowHideProcess(const ProcessSerialNumber *psn, Boolean visible)