TableView with QtQuick 2.12 - qml

I implemented QAbstractTableModel + TableView with QtQuick 2.12 as described in the official QT docs.
my QML code:
import QtQuick 2.12
import TableModel 0.1
TableView {
anchors.fill: parent
columnSpacing: 1
rowSpacing: 1
clip: true
model: TableModel {}
delegate: Rectangle {
implicitWidth: 100
implicitHeight: 50
Text {
text: display
}
}
}
QAbstractTableModel implemented in C++ as described in docs.
Now my app displays a table that can be scrolled.
How to (or is it possible to)
add header that stays visible when the table is
scrolled vertically.
make table rows selectable
use different delegates for different columns
?

In terms of official Qt API, most of it is in the process of being written:
HeaderView is currently being developed: https://codereview.qt-project.org/#/c/255424/
Item selections are currently being developed.
https://stackoverflow.com/a/55517337/904422
Someone else might have answers about how to do this from scratch/manually.

Related

how to set TextField automatically editible without clicking Textfield on qtquick2

i am trying to create a TextField and when the TextField is appeared i want it to become editible even without clicking the Text area. It appears but without clicking on placeholder text which is text area, it is not becoming active. Here is what i tried
import QtQuick 2.12
import QtQuick.Controls 2.0
Item {
TextField {
id: textFieldTest
placeholderText: "This area should appear as clicked"
anchors.centerIn: parent
focus: true
Component.onCompleted: textFieldTest.forceActiveFocus()
}
}
I've also tried to use
focus: true
and
Component.onCompleted: textFieldTest.forceActiveFocus()
seperately. Also together. But both of them did not work. Which function or feature should i use?
Sometimes, you need to delay it, e.g.
Component.onCompleted: Qt.callLater(textFieldTest.forceActiveFocus)
The reason being, is that other components initializing may also want to change focus. So, you want to delay your request for focus so that "last in wins".
Please share your entire code if possible. It seems some thing else is stealing the focus. In my case this is working:
import QtQuick
import QtQuick.Controls
Window {
width: 640
height: 480
visible: true
title: qsTr("Hello World")
TextField {
id: textFieldTest
placeholderText: "This area should appear as clicked"
anchors.centerIn: parent
focus: true
Component.onCompleted: textFieldTest.forceActiveFocus()
}
}

QML: contentItem does not show any Image

I am using QML to design a small user interface.
The problem I have is that I need to select an image if a certain conditions happens or not, and nothing happens because I may have something wrong in the contentItem below, I set a simple a if loop that replicates exactly the problem I have:
main.qml
// operations ....
Row {
anchors.fill: parent
anchors.leftMargin: 20
anchors.topMargin: 20
Button {
id: button
width: 90
height: 270
contentItem: Item {
Image {
source: root.selected === 0 ?
source: "qrc:/images/btn-Modes-on.png" :
source: "qrc:/images/btn-modes-normal.png"
}
}
// operations ....
}
I believe the problem is where I set the if loop for the images. I can confirm that the path of the images is correct and double checked.
I also used according to the documentation the proper notation of the images, and the property I am using is source: "path to your image".
However after checking that I still also have no return.
Thanks for pointing in the right direction to solve this problem.
There's a typo in your code. The Image source should look like this:
source: root.selected === 0 ?
"qrc:/images/btn-Modes-on.png" :
"qrc:/images/btn-modes-normal.png"

Which is the most generic view in Qt Quick Controls 2

I'm learning to work with QML and Qt Quick Controls 2 and try to figure out how to write "proper" applications with it (endgame is a small prototype for embedded devices).
One thing I'm missing is a simple and explicit way to build multi-page applications: there is StackView, TabView and SwipeView, but there is nothing like SimpleView, a component that I could put Page components into and then switch them via custom actions. Currently, I'm mis-using the SwipeView to achieve something similar, by setting interactive property to false, but I have to wonder whether this is a proper way.
So, which is the most generic "page container" component in Qt Quick Controls 2?
Take a look at StackLayout from Qt Quick Layouts. It's a stack of arbitrary items, where you can control the index of the currently visible item.
StackLayout {
anchors.fill: parent
currentIndex: 1
Page {
// ...
}
Page {
// ...
}
}

Querying global mouse position in QML

I'm programming a small PoC in QML. In a couple of places in my code I need to bind to/query global mouse position (say, mouse position in a scene or game window). Even in cases where mouse is outside of MouseAreas that I've defined so far.
Looking around, the only way to do it seems to be having whole screen covered with another MouseArea, most likely with hovering enabled. Then I also need to deal with semi-manually propagating (hover) events to underlying mouseAreas..
Am I missing something here? This seems like a pretty common case - is there a simpler/more elegant way to achieve it?
EDIT:
The most problematic case seems to be while dragging outside a MouseArea. Below is a minimalistic example (it's using V-Play components and a mouse event spy from derM's answer). When I click the image and drag outside the MouseArea, mouse events are not coming anymore so the position cannot be updated unless there is a DropArea below.
The MouseEventSpy is taken from here in response to one of the answers. It is only modified to include the position as parameters to the signal.
import VPlay 2.0
import QtQuick 2.0
import MouseEventSpy 1.0
GameWindow {
id: gameWindow
activeScene: scene
screenWidth: 960
screenHeight: 640
Scene {
id: scene
anchors.fill: parent
Connections {
target: MouseEventSpy
onMouseEventDetected: {
console.log(x)
console.log(y)
}
}
Image {
id: tile
x: 118
y: 190
width: 200
height: 200
source: "../assets/vplay-logo.png"
anchors.centerIn: parent
Drag.active: mausA.drag.active
Drag.dragType: Drag.Automatic
MouseArea {
id: mausA
anchors.fill: parent
drag.target: parent
}
}
}
}
You can install a eventFilter on the QGuiApplication, where all mouse events will pass through.
How to do this is described here
In the linked solution, I drop the information about the mouse position when emitting the signal. You can however easily retrieve the information by casting the QEvent that is passed to the eventFilter(...)-method into a QMouseEvent and add it as parameters to the signal.
In the linked answer I register it as singleton available in QML and C++ so you can connect to the signal where ever needed.
As it is provided in the linked answer, the MouseEventSpy will only handle QMouseEvents of various types. Once you start dragging something, there won't be QMouseEvents but QDragMoveEvents e.t.c. Therefore you need to extend the filter method, to also handle those.
bool MouseEventSpy::eventFilter(QObject* watched, QEvent* event)
{
QEvent::Type t = event->type();
if (t == QEvent::MouseButtonDblClick
|| t == QEvent::MouseButtonPress
|| t == QEvent::MouseButtonRelease
|| t == QEvent::MouseMove) {
QMouseEvent* e = static_cast<QMouseEvent*>(event);
emit mouseEventDetected(e->x(), e->y());
}
if (t == QEvent::DragMove) {
QDragMoveEvent* e = static_cast<QDragMoveEvent*>(event);
emit mouseEventDetected(e->pos().x(), e->pos().y());
}
return QObject::eventFilter(watched, event);
}
You can then translate the coordinates to what ever you need to (Screen, Window, ...)
As you have only a couple of places where you need to query global mouse position, I would suggest you to use mapToGlobal or mapToItem methods.
I believe you can get cursor's coordinates from C++ side. Take a look on answer on this question. The question doesn't related to your problem but the solution works as well.
On my side I managed to get global coordinates by directly calling mousePosProvider.cursorPos() without any MouseArea.

QtDesktop components crash on mouse move

I'm trying to use Qt 5 with QtDesktop components in Windows 8 x64 and when I build and run app and move mouse, app is crashing with this message in log:
QPainter::begin: A paint device can only be painted by one painter at a time.
It happens only if mouse move in any component, if i have qml like this:
import QtQuick 2.0
import QtDesktop 1.0
Rectangle {
width: 360
height: 360
Button {
text: "testButton"
}
Text {
text: qsTr("Hello World")
anchors.centerIn: parent
}
MouseArea {
anchors.fill: parent
onClicked: {
Qt.quit();
}
}
}
everything will be ok before I move cursor into button. Somebody have any ideas what is it and how i can fix this? It isn't the error in my code because building tests/tableviewmodels and examples/ApplicationTemplate gives the same result
If it important, I use Visual Studio 2010 Express + Qt Creator 2.6.1
PS not sure, but I think I build and run QtDesktopComponents on this PC about two weeks ago and there wasn't this error, and it was windows update after that
UPD
It was Qt Quick Components bug, fixed in https://bugreports.qt-project.org/browse/QTCOMPONENTS-1287