55/5000 The QuickItem implementation layer, the underlying control of the qml cascade control, cannot receive QMouseEvent* or QTouchEvent* - qml

contentItem: QuarterViewPositioner {
id: control
spacing: 6
readonly property color backgroundColor: Qt.rgba(0,0,0,1.0)
item0: QImageView3D {
id: iv0
backgroundColor: control.backgroundColor
orientation: 0
property real lastZoom: 1
property real radio: 0.5
property real lastRadio: 0.5
QImageView3D inherit from QQuickFramebufferObject,
QImgaeView3D include a 'control' component named 'ControlTransRot3D' , this 'control' contains the Rectangle contentItem.
ControlTransRot3D {
id: tr0Channel
visible: showChannelRot3D && (uidata.channelListShowModel.count > 0 || uidata.traumaListShowModel.count > 0)
parent: item0
width: 100
height: 100
centerX: 200
centerY: 200
viewType:0
}
Control {
id:ctrl
property real w:0
property real h:0
property real centerX: ctrl.width / 2.0
property real centerY: ctrl.height / 2.0
property bool showUpDownBtn: true
property var viewType: EnumType.VertralSliceA
x: centerX - ctrl.width / 2.0
y: centerY - ctrl.height / 2.0
rotation: 0
property bool rotBtnVisible: true
property int hOffset: -60
// property int sizeBtn: 30
// property int sizeIcn: 16
property int sizeBtn: 33
property int sizeIcn: 30
property string bgColor: "transparent"
contentItem: Rectangle {
id: rectangle
color: "transparent"
anchors.fill: parent
//border.width: 2
//border.color: "#ff0000"
ToolButton {
when i touch the current rectangle on the touchscreen, i can't receive QMouseEvent * or QTouchEvent * on the parent QImageView3D
virtual void mousePressEvent(QMouseEvent* event);
virtual void mouseMoveEvent(QMouseEvent* event);
but when i use mouse to click the rectangle, the parent QImageView3D can receive the QMouseEvent * or QToucheEvent.
It seems that the signal under the touch screen is impenetrable.
The attribute propagateComposedEvents or mouse.accepted has been tried, it does not work.
And I have tried to test in the MouseArea,the MouseArea can capture the signal but cannot receive it in the MouseMoveEvent in the Cpp.

Related

How to pin NSViewController to top of NSPopover during NSViewController.transition?

I've been trying to create a sliding transition from one child view controller to another inside an NSPopover.
My problem is that the child view controllers do not stick to the top of the NSPopover during the transition. They animate in from the bottom or top:
Expected behaviour: both child view controllers should stick to the top during the transition and should simply slide over horizontally.
This is the function I wrote to trigger the transition:
func loadViewController(_ childViewController: NSViewController, withTransition transitionOptions: NSViewController.TransitionOptions?) {
addChild(childViewController)
view.addSubview(childViewController.view)
childViewController.view.layer?.borderColor = NSColor(calibratedRed: 0, green: 255, blue: 0, alpha: 1).cgColor
childViewController.view.layer?.borderWidth = 2
childViewController.view.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
view.layout()
let oldViewController = currentViewController
currentViewController = childViewController
oldViewController?.view.layer?.borderColor = NSColor(calibratedRed: 255, green: 0, blue: 0, alpha: 1).cgColor
oldViewController?.view.layer?.borderWidth = 2
if let oldViewController = oldViewController {
transition(from: oldViewController, to: currentViewController!, options: transitionOptions ?? .slideLeft, completionHandler: { [weak oldViewController] in
oldViewController?.removeFromParent()
oldViewController?.view.removeFromSuperview()
})
}
NSAnimationContext.runAnimationGroup({ (context) -> Void in
context.duration = 0.5
context.allowsImplicitAnimation = true
self.parentPopover?.contentSize = NSSize(width: childViewController.preferredContentSize.width, height: childViewController.preferredContentSize.height)
})
}
Any idea what could be causing the issue? I've tried playing around with the constraints of both the child and parent view controllers as well as their frame sizes. I just can't figure out what I'm doing wrong.
I've uploaded the complete reproducible example here: https://github.com/maximilianschmitt/DebugPopoverAnimation
MasterViewController.swift
ChildViewController.swift
Thanks a lot for your help!
If you expect as on below animation
then just remove update of content size from animation block, as below
self.parentPopover?.contentSize = NSSize(width: childViewController.preferredContentSize.width, height: childViewController.preferredContentSize.height)
NSAnimationContext.runAnimationGroup({ (context) -> Void in
context.duration = 0.5
context.allowsImplicitAnimation = true
}) {
oldViewController?.removeFromParent()
oldViewController?.view.removeFromSuperview()
}
Update: keep popover content animatable (above changes are not needed)
For this case the only you need is to flip coordinate system for popover content view (which is a view of MasterViewController)
class PopoverContentView: NSView {
override var isFlipped: Bool { true }
}
class MasterViewController: NSViewController {
...
override func loadView() {
self.view = PopoverContentView()
}

QML: Move a frameless window by dragging

I have a frameless QQuickWindow, and I want to move it with the mouse by dragging. Before trying in my big application, I have created a simple test application to try what I found here, using cursor position from C++ class to avoid problems from QML:
http://www.tickanswer.com/solved/5390888353/dragging-frameless-window-jiggles-in-qml
But I failed with the code below. When I press over the red RECT and move the mouse, my yellow rect (root RECT) moves, but only inside the original size it had (in this case, 500x500)... What am I doing wrong?
Thanks in advance
In my main.cpp:
int main(int argc, char *argv[])
{
QtQuickControlsApplication a(argc, argv);
QQuickView* pView = new QQuickView();
CursorPosProvider mousePosProvider;
pView->rootContext()->setContextProperty("mousePosition", &mousePosProvider);
pView->setSource(QUrl("qrc:/Test.qml"));
pView->setFlags(Qt::FramelessWindowHint);
pView->show();
return a.exec();
}
Test.qml:
import QtQuick 2.0
Rectangle {
id: myWindow
width: 500; height: 500
color: "yellow"
Rectangle {
anchors.centerIn: parent
width: 200; height: 200
color: "red"
MouseArea {
id: titleBarMouseRegion
property var clickPos
anchors.fill: parent
onPressed: clickPos = { x: mousePosition.cursorPos().x, y: mousePosition.cursorPos().y }
onPositionChanged: {
myWindow.x = mousePosition.cursorPos().x - clickPos.x
myWindow.y = mousePosition.cursorPos().y - clickPos.y
}
}
}
}
cursorprovider.h:
#ifndef CURSORPOSPROVIDER_H
#define CURSORPOSPROVIDER_H
#include <QObject>
#include <QPointF>
#include <QCursor>
class CursorPosProvider : public QObject
{
Q_OBJECT
public:
explicit CursorPosProvider(QObject *parent = nullptr) : QObject(parent)
{
}
virtual ~CursorPosProvider() = default;
Q_INVOKABLE QPointF cursorPos()
{
return QCursor::pos();
}
};
#endif // CURSORPOSPROVIDER_H
I wrote this example and I see no jiggle (running on Linux)
ApplicationWindow {
id: iWindow
visible: true
title: "My title"
color: "gray"
width: 500
height: 500
MouseArea{
id: iMouseArea
property int prevX: 0
property int prevY: 0
anchors.fill: parent
onPressed: {prevX=mouse.x; prevY=mouse.y}
onPositionChanged:{
var deltaX = mouse.x - prevX;
iWindow.x += deltaX;
prevX = mouse.x - deltaX;
var deltaY = mouse.y - prevY
iWindow.y += deltaY;
prevY = mouse.y - deltaY;
}
}
}
I have changed the structure, I have used a QQuickWidget with a QML inside, and now I have what I wanted. Here is my code in case anyone needs something similar
main.cpp
...
MovableWidget *view = new MovableWidget;
view->setSource(QUrl("qrc:/Test.qml"));
view->setWindowFlags(Qt::FramelessWindowHint);
view->show();
...
Test.qml
import QtQuick 2.0
Rectangle {
id: myWindow
width: 500; height: 500
color: "yellow"
Rectangle {
anchors.centerIn: parent
width: 200; height: 200
color: "red"
}
}
MovableWidget.cpp
#include "movableWidget.h"
#include <QMouseEvent>
// ****************************************************************************
MovableWidget::MovableWidget(QWidget *parent)
: QQuickWidget(parent),
m_previousPos(0,0)
{
installEventFilter(this);
}
// ****************************************************************************
bool MovableWidget::eventFilter(QObject *obj, QEvent *event)
{
if (event->type() == QEvent::MouseButtonPress)
{
m_previousPos = QCursor:os();
}
else if (event->type() == QEvent::MouseMove)
{
QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
if(mouseEvent->buttons() == Qt::LeftButton)
{
QPoint offset = m_previousPos - QCursor:os();
m_previousPos = QCursor:os();
move(pos() - offset);
}
}
return false;
}

Xamarin: iOS 7 UITextField Padding

What's the "easiest" way to add padding (all four sides) to a UITextField in Xamarin for iOS 7. Following code doesn't seem to work on iOS7.
textField.LeftView = new UIView (new RectangleF (0, 0, 10, 10));
textField.LeftViewMode = UITextFieldViewMode.Always;
Then I tried to subclass UITextField to try another option...
public class TextFieldBase : UITextField
{
public TextFieldBase (IntPtr handle) : base (handle)
{
}
public override RectangleF TextRect(RectangleF bounds){
return RectangleF.Inflate( bounds , 10 , 10 );
}
public override RectangleF EditingRect(RectangleF bounds){
return RectangleF.Inflate( bounds , 10 , 10 );
}
}
That didn't work either.
I'm not sure if what I have set in the interface builder is overriding what I have in the subclass code.
Subclass UITextField and override TextRect, EditingRect:
public override CoreGraphics.CGRect EditingRect (CoreGraphics.CGRect forBounds) {
return base.EditingRect (InsetRect (forBounds, new UIEdgeInsets (0, 10, 0, 10)));
}
public static CoreGraphics.CGRect InsetRect(CoreGraphics.CGRect rect, UIEdgeInsets insets)
{
return new CoreGraphics.CGRect(rect.X + insets.Left, rect.Y + insets.Top,
rect.Width - insets.Left - insets.Right, rect.Height - insets.Top - insets.Bottom );
}
You might want to try subclassing UITextField and overriding the following methods:
- (CGRect)textRectForBounds and -(CGRect)editingRectForBounds.
You can then adjust the bounds, height, and width to get the desired effect.

Copying Rectangles Automatically in Qml

Is it possible to make a certain amount of copies of a rectangle maybe by using a for loop or by any other way with the ability of changing each rectangle attributes like x,y,width etc.. by using QML
I have tried the following :
var x = 0
var t = 80
var z = 125
var Rectangle = []
if(rs.rows.length > 0){
x = 2
for(var i = 0; i < rs.rows.length; i++){
Rectangle[i] = rectangle18
Rectangle[i].x = t
Rectangle[i].y = z
Rectangle[i].visible = true
t = t - 40
z = z - 7
}
}
But unfortunately it's not working with me, is there a way of making this working
It's not quite that simple. You need to use Qt.createComponent and that object's createObject() call to achieve what you want. It's not just a matter of creating the rectangle and then copying it, you need to load each new copy separately from a qml file.
Something like:
var rects = []
var creator = Qt.createComponent("myRect.qml")
for (var i = 0; i < 10; i++) {
rects[i] = creator.createObject(PARENT)
rects[i].x = ...
}
Obviously extrapolating it to what you need. Note the reference to PARENT, which is the object that should end up containing the rectangle, which is often a container like a Grid or something.
If you don't want to use the Qt.CreateComponent method you can also consider using a Repeater component with a ListModel containing the info for each Rectangle. Here is an example placing 4 Rectangle in the scene:
ListModel {
id: modelRects
ListElement { _x: 0; _y:0 ; _width: 10; _height: 10; _color: "red" }
ListElement { _x: 100; _y:0 ; _width: 20; _height: 20; _color: "blue" }
ListElement { _x: 0; _y:100 ; _width: 30; _height: 30; _color: "yellow" }
ListElement { _x: 100; _y:100 ; _width: 40; _height: 40; _color: "green" }
}
Repeater {
model: modelRects
delegate: Rectangle {
width: _width
height: _height
x: _x
y: _y
color: _color
}
}
If you don't want to create the ListModel you can also base your calculations on the index of the element. Here is an example growing the Rectangle based on the index:
Repeater {
model: 5
delegate: Rectangle {
// Index starts at 0 so you want a width higher than 0 on first element
width: 10 * (index + 1)
height: 10 * (index + 1)
x: 50 * index
y: 50 * index
color: "red"
}
}

property location in qml

I have error
ReferenceError: redRow is not defined
on this code:
Repeater {
property int redRow: 0
...
Image {
...
anchors.bottom: parent.bottom
anchors.bottomMargin: height / 16 + height * redRow
...
}
if i put
property int redRow: 0
in the begin of file - all right, why i don't have a opportunity put this in Repeater element?
You can put this in the repeater but you have to reference this variable by the id of repeater:
Repeater {
id: repeater //add id to the repeater this can be any unique identifier
property int redRow: 0
...
Image {
...
anchors.bottom: parent.bottom
anchors.bottomMargin: height / 16 + height * repeater.redRow //reference repeaters property
...
}
}