I am using Qt5 beta and trying to embed a QWidget-based object into QML. The goal is to use QML as much as possible, and only use QWidget objects where QML does not do what I need. I found a link explaining how to do this for Qt4.7, but I have not found any information explaining how to do this in Qt5.
http://doc.qt.digia.com/4.7/declarative-cppextensions-qwidgets.html
The same example is also available in the Qt5 examples folder under:
examples\qtquick1\declarative\cppextensions\qwidgets
Unfortunately, this example uses QtQuick 1, rather than QtQuick 2, and I would like to use the new features of Qt5. I actually want to embed a qwt widget, but as a first step I would be happy to embed any simple QWidget-based object.
Can anybody help me get the example working under Qt5 / QtQuick 2 ?
Qt Quick 2 uses a scene graph for efficient rendering on the GPU. Unfortunately this makes it impossible to embed classic widgets into the scene. The old approach to embed such widgets with the help of QGraphicsProxyWidget works only with Qt Quick 1, because internally it uses a QGraphicsView for all the heavy lifting and QGraphicsProxyWidget is meant to be used with it.
As of now there are no plans to enable embedding classic QWidgets into the scene graph I know of. I think this is rather unlikely to change, because the concepts of QPainter, the painting framework used for the classic widgets, and the new scene graph doesn't play well with each other.
There some efforts to develop new widgets sets specifically tailored for the needs of QML, but none of them are as powerful and mature as the classic widgets. The most prominent ones are the QML Quick Controls, bundled with Qt since version 5.1.
If you really depend on QWT my advice would be to stick with Qt Quick 1.1 for now. It's still bundled with Qt 5, probably for cases like yours. That way you won't take advantage of the new scene graph, though.
You can embed QWidget to QML by using QQuickPaintedItem class:
http://doc.qt.io/qt-5/qquickpainteditem.html
Qt5 has an example:
http://doc.qt.io/qt-5/qtquick-customitems-painteditem-example.html
You should implement an inherent of QQuickPaintedItem with private widget attribute, that you want to embed. Provide paint method, that just render the QtWidget and provide mouse and other event transmitting from inherit of QQuickPaintedItem to embed QtWidget.
There's also QSG (Qt scene graph API), but my experience with that thing wasn't smooth. I believe the clue in multithreading (performing rendering in the different thread (not the Qt GUI thread one, however on Windows that's not true and all is done in main GUI thread).
I've implemented embedding of QCustomPlot, here's link: github.com/mosolovsa/qmlplot
What could be done is to render the widget to an image and upload as texture.For interaction someone needs to forward events like mouseClick or keyPressed from the sceneGraph, translate to widget coordinates, pass on, render and upload texture again. Just an idea :)
The recommended approach is to stay with a QWidget based application and embed the QML parts using QWidget::createWindowContainer.
Further to Julien's answer - a simple way to achieve this is to use QQuickWidget to display the QML scene, and then add a regular QWidget as a child of the QQuickWidget. You can also add a simple intermediate QObject to anchor the QWidget to an item in the scene.
E.g.:
In main.qml:
Item {
... // layouts, extra items, what have you
Item
{
objectName: "layoutItem"
anchors.fill: parent
}
... // more layouts, extra items, etc.
}
widgetanchor.h:
class WidgetAnchor: public QObject
{
ptr<QWidget> _pWidget;
QPointer<QQuickItem> _pQuickItem;
public:
WidgetAnchor(QWidget* pWidget, QQuickItem* pItem)
: QObject(pWidget), _pWidget(pWidget), _pQuickItem(pItem)
{
connect(_pQuickItem, &QQuickItem::xChanged, this, &WidgetAnchor::updateGeometry);
connect(_pQuickItem, &QQuickItem::yChanged, this, &WidgetAnchor::updateGeometry);
connect(_pQuickItem, &QQuickItem::widthChanged, this, &WidgetAnchor::updateGeometry);
connect(_pQuickItem, &QQuickItem::heightChanged, this, &WidgetAnchor::updateGeometry);
updateGeometry();
}
private:
void updateGeometry()
{
if (_pQuickItem)
{
QRectF r = _pQuickItem->mapRectToItem(0, QRectF(_pQuickItem->x(), _pQuickItem->y(), _pQuickItem->width(), _pQuickItem->height()));
_pWidget->setGeometry(r.toRect());
}
}
};
In main.cpp:
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
auto pqw = new QQuickWidget;
pqw->setSource(QUrl::fromLocalFile("main.qml"));
pqw->setResizeMode(QQuickWidget::SizeRootObjectToView);
pqw->setAttribute(Qt::WA_DeleteOnClose);
auto pOwt = new MyWidget(pqw);
if (auto pOverlayItem = pqw->rootObject()->findChild<QQuickItem*>("overlayItem"))
new WidgetAnchor(pOwt, pOverlayItem);
pqw->show();
return app.exec();
}
The documentation states that using QQuickWidget has advantages over QQuickView and QWidget::createWindowContainer, such as no restrictions on stacking order, but has a 'minor performance hit'.
Hope that helps.
Related
I am building my custom UIControl, a custom button built as an IBDesignable, which needs to change based on the size class in which it is being displayed. I have a method -setupForTraitCollection, which looks like this:
func setupForTraitCollection() {
switch(traitCollection.horizontalSizeClass, traitCollection.verticalSizeClass) {
case (.Regular, _):
// iPad - not compressed design
compressed = false
default:
// iPhone - compressed design
compressed = true
}
}
This code works great when compiled, but in live rendering, and when debugging the view, it never hits the "iPad" switch case. I am starting to give up here and simply accept that traitCollections aren't available in live rendering, but I'd like to have this confirmed. Better still, if someone could point me in the direction of finding a solution.
So the to-the-point question is - Can I use traitCollections in an IBDesignable and if so, how?
I'd really like to be able to change size class in IB and see the result on my custom control.
Interface Builder does not yet set the trait collection for designable views when we are rendering in Xcode. We are tracking this with radar://17278773. Filing a report at http://bugreport.apple.com and mentioning that bug ID will help us track demand and prioritize appropriately.
My code looks like this:
QApplication app(argc, argv);
QQmlApplicationEngine app_engine;
app_engine.load("qml/main.qml");
return app.exec();
Could somebody please help me how to make Qt render everything to the buffer I provide? OpenGL must be avoided. I could make this work with QWebPage, but this appears to be much more difficult to me...
I've found the way to get the QML output as QImage, but it works only if the QML window has focus. Incomplete code snippet follows:
QApplication app(argc, argv);
QQmalApplicationEngine *appEngine = new QQmlApplicationEngine(this);
appEngine->load(script_path);
...
app.exec();
While app is running, you can grab window contents like this:
QQuickWindow *win = qobject_cast<QQuickWindow *>(appEngine->rootObjects().first());
QImage grabbed = win->grabWindow();
It has several drawbacks (i.e. cursor disappears when the input focus is lost, grabWindow() is very slow etc.).
Furthermore, it's also possible to redirect QML page rendering to a custom FBO, this provides a much faster solution but also suffers from some issues.
I'm exploring JavaFX and I must say I'm little disappointed with the lack of learning material. I'm rookie to JavaFX but I have some experience with Swing.
How can I place the slider vertically?
And one more question,I want the Thumb to be draggable only to the Tick marks,not in the intermediate space,how can I achieve that?
How can I place the slider vertically?
Use setOrientation
slider.setOrientation(Orientation.VERTICAL);
I want the Thumb to be draggable only to the Tick marks,not in the intermediate space,how can I achieve that?
Use setSnapToTicks after setting an appropriate tick unit, count and block increment.
slider.setMajorTickUnit(0.25f);
slider.setMinorTickCount(1);
slider.setBlockIncrement(0.125f);
slider.setSnapToTicks(true);
Sample app:
import static javafx.application.Application.launch;
import javafx.application.*;
import javafx.event.*;
import javafx.geometry.Orientation;
import javafx.scene.*;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.stage.Stage;
public class VerticalSliderSample extends Application {
#Override public void start(Stage stage) {
Slider slider = new Slider(0, 1, 0.5);
slider.setShowTickMarks(true);
slider.setShowTickLabels(true);
slider.setMajorTickUnit(0.25f);
slider.setMinorTickCount(1);
slider.setBlockIncrement(0.125f);
slider.setSnapToTicks(true);
slider.setOrientation(Orientation.VERTICAL);
VBox layout = new VBox(10);
layout.setStyle("-fx-background-color: cornsilk; -fx-padding: 10;");
layout.getChildren().setAll(slider);
stage.setScene(new Scene(layout));
stage.show();
}
public static void main(String[] args) { launch(args); }
}
I'm exploring JavaFX and I must say I'm little disappointed with the luck of learning material.
Email (constructive) feedback on Oracle developed JavaFX documentation to:
jfx-docs-feedback_ww#oracle.com
With Java 8 and with it JavaFX 8 and its corresponding SceneBuilder coming (at this time of post its still Java 7 GA with SceneBuilder 2.2), people should get more familiar using it. It is a powerful tool for people who don't know each special attribute from its hat off and want to practice the Inversion of Control principle the new JavaFX and its FXMLs offer us.
Here is an example out of one of my projects to show the most popular
properties on each Node
Though I can sometimes understand you, for being frustrated especially if some new features come out, that some higher class examples what this Node can do and maybe find it easier, but as a programmer you need to learn to work with the corresponding API. It would be nice to have a part of each API documentation like in the PHP community where you can maintain it as a wiki.
A slightly odd question, but is there anyway to find out what easing functions are used in the WinRT XAML Theme Animations - more specifically I'm trying to replicate that of the EntranceThemeTransition (which I can't use directly).
I naively thought using something like .NET reflector would help, but I'd gather I'd need the actual source code rather than what .Net Reflector shows.
Anyone any ideas?
You might like to take a look at the AnimationMetrics sample on MSDN.
There is an AnimationDescription class that will tell you all sorts of info on the built in animation types, basically anything in the Windows.UI.Core.AnimationMetrics.AnimationEffect enum.
For example:
var animationDescription = new AnimationDescription(AnimationEffect.EnterPage, AnimationEffectTarget.Incoming);
var s = new System.Text.StringBuilder();
s.AppendFormat("Stagger delay = {0}ms", animationDescription.StaggerDelay.TotalMilliseconds);
s.AppendLine();
s.AppendFormat("Stagger delay factor = {0}", animationDescription.StaggerDelayFactor);
s.AppendLine();
s.AppendFormat("Delay limit = {0}ms", animationDescription.DelayLimit.TotalMilliseconds);
s.AppendLine();
s.AppendFormat("ZOrder = {0}", animationDescription.ZOrder);
s.AppendLine();
s.AppendLine();
//etc
Link: http://code.msdn.microsoft.com/windowsapps/Animation-metrics-sample-acb0220c
I believe these built in animations are implemented in a different way and they run independently from regular Storyboard + child animations, so you would need to approximate these with some tests that compare these with regular Storyboard animations that you implement running side by side.
One way to visualize easing functions is to run a theme transition moving a UI element in one axis while you run another one that moves the element in a perpendicular axis in a linear motion (with no easing function applied).
Does Xcode support anything akin to Visual Studio style #region directives for arbitrary code folding?
No, you can only fold code on various defined scoping levels in Xcode.
You can use little tricks to make navigating via the function menu easier, though.
#pragma mark
Allows you to create a grouping where the label following mark will show up in the function menu. If the label is a hyphen, a separator is inserted into the function menu.
Also, the following labels in comments will show up in the function menu:
// MARK:
// TODO:
// FIXME:
// !!!:
// ???:
Obviously since #pragma mark is not really portable, if you're building a portable application and need it to work with a compiler that doesn't just ignore #pragma directives that it doesn't understand, the comment-style mark is a decent alternative.
I am going to hell for this but here goes:
At the top of a given file, put
#define FOLD 1
Wherever you want to fold something, wrap it in an if block like so:
if(FOLD) {
// your code to hide
// more code
}
That will let you fold it away out of sight.
That won't work in the place you want it most, that is, around groups of functions or methods.
It may be useful inside a long, linear method with no internal conditionals or loops, but such methods aren't common in general Mac OS X UI code, though if you're writing some big numeric or graphics-crunching code it could help group things.
And the if(fold) is entirely superfluous. Just use the braces inside a method or function and Xcode will fold them.
Try this way :
//region title1
{
//region Subtitl1
{
}
//region Subtitl2
{
}
}
It can do like that :
Without support for .Net style regions, being able to collapse all your functions at the same time is the next best thing.
command-option-shift-left arrow
to collapse all.
command-option-shift-right arrow
to expand all.
Xcode will remember the last state of collapsed functions.
A useful option in XCode 12 (maybe before), is an option in preferences "Code Folding Ribbon"
When you check it, the source code looks like this
When you hover the mouse over this ribbon, you get foldable regions based on brackets, like this
When you click the Ribbon, it folds the bracket region, like this
Its not as the regions in Visual Studio, where you can place them wherever you want, but they're good enough to tidy up your code files.
To answer your question...No. And It drives me nuts.
If you have the opportunity/ability you can use AppCode for this. I've been using it for a few years and it usually beats Xcode in many areas.
Also I specifically use AppCode because of these features:
Ability to use regions
Searching classes, text and usages is MUCH faster.
Refactoring is also faster.
Cleaner and more customizable UI.
Tabs are handled (in my opinion) much better than in Xcode.
FOLDING. You can actually change what levels of folding you want. Why Apple thought there should be no quick-key to fold extensions is beyond me. And fold ribbons? Really Apple? Yes they're pretty and all but most professionals use hotkeys for everything.
Better GIT integration.
Support for live updates in SwiftUI
If you use other Jetbrains IDE's like PyCharm or Android Studio the UI is exactly the same.
Some downsides of AppCode:
Some things that work in Xcode aren't supported
Visual #colorLiteral(). When using them they don't show a color picker.
No Storyboard support. Annoying to have to open up Xcode. If you write your UI in code this is a moot point.
Editing .plist files isn't as nice. Doable, but not nice.
Initial indexing can take a while.
Cost. But I would argue the time savings in just navigation will compensate for this.
Kind of a lot for a simple question but I think it's nice having alternatives.
Put your desired code inside brackets { }, and it will become a folding zone.
But you have to keep in mind that brackets also define variables scope, so this code should not have variables declarations which will be used outside these brackets.
One nice solution I just found:
Put your project into one big namespace.
Close and reopen this namespace for the individual sections of your source file:
namespace myproj { // members of class MyClassA
void MyClassA::dosomething()
{
}
void MyClassA::dosomethingelse()
{
}
} // members of class MyClassA
namespace myproj { // members of MyClassB
void MyClassB::dosomething()
{
}
void MyClassB::dosomethingelse()
{
}
} // members of MyClassB