Expose and add QWebView widget object to QML - c++

QML has a type called 'WebView', this thing is also known as 'QQuickWebView'. But 'QQuickWebView' is not compatible with 'QWebView' (which is a widget component, not QML type).
I want to access and modify 'WebView' in C++ but the closest class that I can cast for WebView is 'QQuickItem'.
Any solution to make QWebView embeddable in QML?

In QML, use "import QtWebKit.experimental 1.0"
Reference:
http://rschroll.github.io/beru/2013/08/21/qtwebview.experimental.html

Related

Qt 5.10 - How to add a chart example to a layout

It's my very first experience with Qt so i hope its a basic question with a basic answer I couldn't find. I need to add a "custom" chart widget
(like in the following example: https://doc.qt.io/qt-5.10/qtcharts-zoomlinechart-example.html)
to some Qt container like "layout" or "form". Its very straightforward when you have the widget in the toolbox and you use the designer but since it is a custom widget i cannot do that.
How do you do this in Qt creator?
If your Chart class inherits from QWidget, you have two ways to do this:
In the Design mode, put a QWidget on your Window, or into a Layout. Then, right click on it and select "Promote to ...". There, write your class name in "Promoted class name".
In your window cpp file, write:
YourChartClass* ycc = new YourChartClass(this);
ycc.show();
or
YourChartClass* ycc = new YourChartClass();
this->layout()->addWidget(ycc)
If your chart inherits from another class, and that class inherits from QWidget, the code lines are the same.

Accessing Qt API from JavaScript with QJSEngine

I'm using a QJSEngine to make an application scriptable. I'd like the JavaScript side to be able to modify the user interface. My main issue right now is accessing the Qt API from JavaScript.
To create widgets, I added a createWidget() wrapper that uses QUILoader:
// JavaScript
var w = helpers.createWidget("QPushButton");
// C++
QJSValue helpers::createWidget(QString type)
{
QUILoader ld;
return engine.newQObject(ld.createWidget(type));
}
I've also registered all the enums from qt_getQtMetaObject(), which seems to take care of all the namespace-level enums from qnamespace.h. It doesn't look like it's part of the public API though.
Am I really supposed to this stuff manually or am I missing something? Isn't there a registerAllTheThings() function that creates a global Qt object through which the Qt API available?
If there isn't, then I have a problem. I can create QWidgets with a QUILoader, but I couldn't find a way of creating other objects, such as a QStandardItemModel. I thought all Qt classes would already be registered through qRegisterMetaType(), but they're not: QMetaType::type("QStandardItemModel") fails by returning UnknownType. Again, am I missing some initialization function call that registers everything?
I would recommend using a QQmlEngine instead of the QJSEngine.
Is is derived from QJSEngine so it can do the same things, in the same module so no extra dependencies.
It provides an easy way to register types for instantiation in QML, has a plugin loading mechanism (imports), etc.
I presented that as part of my talk at Qt World Summit 2015: https://www.youtube.com/watch?v=7LsKoVrb8C8

QT QML Items both in C++ and QML

My goal is to describe a qml item in a qml file and then use a corresponding C++ class to add to the visual representation of this item.
I know it is possible to describe a qml item and use it in qml file and the communicate with it from c++ through signal/slots.
I also know it is possible to describe a qml item in C++ using QQuickPaintedItem and use it in a qml file (making it available through the register mechanism). Are there other ways?
So, the actual question is it possible to combine both in one item?
So, I want to have a qml item and a c++ class painting the same area, e.g. I have specific OpenGL code in c++ and a usual Rectangle Frame with MouseArea defined in qml.
After the hint from Andrej I decided to realize my goal of having both the qml representation and a C++ rendering class by creating a wrapper class which derives from QQuickPaintedItem and by this overriding the paint method. With this I can render into the item in code. The item is used in my main qml file.
It is a wrapper class because it loads the qml file I want to show through a QQmlComponent which creates the QuickItem I want to show, too. I do this by setting the parent of the loaded/created item to my wrapper class.
So in my QuickPaintedItem class (best done in classbegin, when engine is already initialized):
QQmlComponent component(engine,QUrl("qrc:/myqml.qml"));
QObject* object = component.create();
QQuickItem* quickItem = qobject_cast<QQuickItem*>(object);
quickItem->setParentItem(this);
Then myqml.qml is rendered and my paint method, too. And I have a central place where I can use both.
After the comments from Velkan, another way is to put the loading of the component in a Loader qml item:
Wrapper { Loader{ onQmlChanged: source = newQml } }
where onQmlChanged would be a slot which consumes a signal:
signal onQmlChanged(string newQml);
I cannot say which way is better performance wise. Defining the structure in qml seems easier and cleaner. A difference to the code version, is that it loads the item at creation time of the Wrapper, so during the creation of the main.qml and before it is shown.

Custom class in qt creator

I'm new to Qt and fairly new to C++ but I need help with this issue.
I have a custom class called HybridStack and I want it to extend a QStackedWidget and a QMainWindow.
I want it to extend a QStackedWidget so that I can use as many pages as I need and I want it to extend a QMainWindow so that I could be able to make each page have it's own MenuBar with different content of menu for different page.
I want to add this custom class HybridStack to Qt Designer by
promoting it from a QStackedWidget.
Is this possible? If it is, can you brief me on how to do this? If it's not possible then what's an alternative? Most importantly, I need to use it in the Designer because I need to use qmake
You can't derive from both QStackedWidget and QMainWindow, because both of those are in turn derived from QWidget. If you did so, you'd end up with the Dreaded Diamond. You'll have to use composition instead.
Even then, I'm not sure if it would work correctly to put a QMainWindow within a QStackedWidget, since it is designed to be a top-level item (i.e. its shown directly as a window, not embedded within another QWidget). Another way of accomplishing what you want (menu bar changing when the you change tabs) would be the following:
Make your top-level item a QMainWindow
Make the central widget a custom widget derived from QStackedWidget
When the item showing in the stack widget changes, you can call QMainWindow::setMenuBar to change the menu bar. Each widget within the QStackWidget could have its own QMenuBar instance that it uses for this purpose.

Can I implement methods of a QWebView from a ui?

I use Qt designer to make an interface and I have an QWebView in it. I would like to reimplement the fonction mouseDoubleClickEvent of my QWebView.
Can I do that? I know I have to use ui->webview to access it, I know I can use the signals easily with on_webView_selectionChanged for example, but what about other methods like mouseDoubleClickEvent?
Since mouseDoubleCLickEvent is a virtual protected function, you will need to subclass QWebView and re-implement the method in your subclass. The documentation for mouseDoubleClickEvent, a method of QWidget, can be found here. After this, you will probably want to integrate your custom widget with Qt Designer. I am not familiar with the program, but this documentation might prove useful. (Edit: it appears that promoting a custom subclass of QWebView requires additional steps which are documented here and here) I do not know of any pure GUI method for creating the custom subclass you need.