How stop QML Combobox Popup's items to be rendered outside - user-interface

I'm trying to create a Combobox in QML with custom items in it.
Each item must have two Labels/text.
I'm trying to customize it, changing the background etc. but the Items in the popup are rendering outside of its borders
How can I contain the items inside the popup?
This is the closest sample code I could get:
import QtQuick 2.13
import QtQuick.Controls 2.2
import QtQuick.Layouts 1.13
import QtGraphicalEffects 1.15
ComboBox {
ListModel {
id: _dataModel
ListElement {
name: "Account1"
numbers: "12345"
}
ListElement {
name: "Account2"
numbers: "12346"
}
ListElement {
name: "Account3"
numbers: "12346"
}
ListElement {
name: "Account4"
numbers: "12346"
}
ListElement {
name: "Account5"
numbers: "12346"
}
ListElement {
name: "Account6"
numbers: "12346"
}
}
id:equipmentList
anchors.verticalCenter: parent.verticalCenter
width: 400
height: 50
model: _dataModel
background: Rectangle {
color: "#95A4A8"
border.color: "white"
}
delegate: ItemDelegate {
id:itemDlgt
width: equipmentList.width
height: 80
contentItem: Column {
id:rectDlgt
width:parent.implicitWidth
spacing: 2
Text {
id: _firstLabel
Layout.preferredHeight: 20
horizontalAlignment: Text.AlignLeft
elide: Text.ElideRight
color: "black"
font.pixelSize: 16
text: name
}
Text {
Layout.preferredHeight: 16
color: "grey"
font.pixelSize: 14
text: numbers
}
}
}
contentItem: Text {
leftPadding: 20
rightPadding: equipmentList.indicator.width + equipmentList.spacing
text: "This doesnt work either"
font: equipmentList.font
color: "white"
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignLeft
elide: Text.ElideRight
}
popup: Popup {
id:comboPopup
visible: true
y: equipmentList.height - 50
width: equipmentList.width
height:contentItem.implicitHeigh
padding: 1
contentItem: ListView {
id:listView
implicitHeight: 150
model: equipmentList.popup.visible ? equipmentList.delegateModel : null
ScrollIndicator.vertical: ScrollIndicator {}
}
background: Rectangle {
radius: 7
border.width: 1
}
}
}

Related

Swipview laggy on swiping

I have bad problem on my qml code performance, laggy when swiping between "Inbox" and "MyBoxes", code is simple but...
Ok, here is my code, main:
Loader {
id: loader
anchors.fill: parent
sourceComponent: splash
}
Component {
id: splash
Splash {
percent: l_i.load
fin: ()=>{
loader.sourceComponent = swip_cmp
}
}
}
Component {
id: swip_cmp
Swip {
}
}
Swip.qml:
Page {
SwipeView {
id: swipeView
topPadding: 10
anchors.fill: parent
currentIndex: tabBar.currentIndex
Inbox {
title: "Inbox"
}
MyBoxes {
title: "MyBoxes"
}
}
header: Navigation {
id: tabBar
pageIndex: swipeView.currentIndex
implicitHeight: 50
width: parent.width
anchors.top: head.bottom
anchors.topMargin: 0
tabs:[
NavButton { text: "Inbox"; icon.source: "../assets/Inbox.png" },
NavButton { text: "MyBoxes"; icon.source: "../assets/Box.png" },
NavButton { text: "Leitners"; icon.source: "../assets/Cards.png" }
]
}
}
MyBoxes.ui.qml:
Page {
Rectangle{
id: page
width: parent.width * .9
anchors.horizontalCenter: parent.horizontalCenter
Column {
spacing: 5
Box {
width: page.width
active: true
title: "504"
totalwords: "504"
details: "Lorem ipsum is placeholder text commonly used in the graphic, print, and publishing industries for previewing layouts and visual mockups."
}
Box {
width: page.width
title: "504"
totalwords: "504"
details: "Lorem ipsum is placeholder text commonly used in the graphic, print, and publishing industries for previewing layouts and visual mockups."
}
}
}
}
Box.qml:
Item {
id: item2
property string title: "title"
property string totalwords: "totalwords"
property string details: "details"
property string src: "src"
property bool online: false
property bool active: false
height: head.contentHeight+det.contentHeight + 50
Rectangle {
id: bodybg
anchors.fill: parent
color: "#FFFFFF"
Text {
id: head
color: "#373737"
text: title
font.bold: true
font.pointSize: 14
anchors.leftMargin: 5
anchors.topMargin: 5
anchors.left: parent.left
anchors.top: parent.top
}
Text {
id: tw
color: "#777777"
text: totalwords
font.bold: true
font.pointSize: 10
anchors.top: parent.top
anchors.topMargin: 5
anchors.right: parent.right
anchors.rightMargin: 5
}
Rectangle {
id: hr
width: parent.width * .9
height: 1
color: "#707070"
anchors.top: head.bottom
anchors.topMargin: 5
anchors.horizontalCenter: parent.horizontalCenter
}
Text {
id: det
width: parent.width
color: "#222222"
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
text: details
anchors.margins: 5
anchors.top: hr.bottom
anchors.right: parent.right
anchors.left: parent.left
}
Button {
id: add
width: 64
height: 26
text: online ? "Download" : (active ? "Deactive" : "Active")
anchors.right: parent.right
anchors.top: det.bottom
anchors.rightMargin: 5
anchors.bottomMargin: 5
contentItem: Rectangle {
id: rectangle
anchors.fill: parent
color: (active ? "#BC0C52" : "#00C193")
Text {
text: add.text
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
color: "#FFFFFF"
}
}
}
Text {
id: delt
visible: !online
color: "#BC0C52"
text: "Delete"
anchors.verticalCenter: add.verticalCenter
anchors.right: add.left
anchors.rightMargin: 10
font.underline: true
}
}
DropShadow {
anchors.fill: bodybg
samples: 17
color: "#80000000"
source: bodybg
}
}
I have no matter cpp code yet!
It's mostly code:|
I think Box.qml must optimize, or may problem be because of long texts in MyBoxes.ui.qml
Or maybe I should change compile configuration, here is qmake:
-spec android-clang "CONFIG+=debug" "CONFIG+=qml_debug" ANDROID_ABIS="armeabi-v7a" && D:/Android/SDK/ndk/21.1.6352462/prebuilt/windows-x86_64/bin/make.exe qmake_all
You can try setting cached: true on the DropShadow:
This property allows the effect output pixels to be cached in order to improve the rendering performance. Every time the source or effect properties are changed, the pixels in the cache must be updated. Memory consumption is increased, because an extra buffer of memory is required for storing the effect output.
It is recommended to disable the cache when the source or the effect properties are animated.
By default, the property is set to false.
https://doc.qt.io/qt-5/qml-qtgraphicaleffects-dropshadow.html#cached-prop

How to display a larger version of selected image in GridView when it is clicked in QML

I am trying to display a larger version of image inside the GridView when it is clicked, and when I pressed esc button, it will bring me back in the GridView of images, but I can't find a way how to display it in QML, This is my code:
import QtQuick 2.9
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.0
import Qt.labs.folderlistmodel 1.0
import QtQuick.Controls 1.1
import QtQml.Models 2.1
import "qrc:/assets/."
Rectangle {
visible: true
Item {
id: theAboveList
}
GridView {
interactive: false
id: gridView
anchors {
top: parent.top
bottom: parent.bottom
left: parent.left
right: parent.right
leftMargin: 5
topMargin: 5
}
cellWidth: width / 2
cellHeight: height / 2
model: folderModel
delegate: fileDelegate
FolderListModel {
id: folderModel
nameFilters: ["*.jpg"]
folder: "file:///E:/QT Projects/ImageViewer/image"
}
Component {
id: fileDelegate
Item {
Image {
width: gridView.cellWidth - 5
height: gridView.cellHeight - 5
smooth: true
source: fileURL
}
}
}
anchors
{
left: parent.left
top: theAboveList.bottom
right: parent.right
bottom: parent.bottom
}
verticalLayoutDirection: GridView.BottomToTop
clip: true
header: Item {}
onContentHeightChanged: {
if (contentHeight < height) {
headerItem.height += (height - contentHeight)
}
currentIndex = count-1
positionViewAtEnd()
}
MouseArea {
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
[ This is where I want to show the clicked image ]
}
}
}
Here is simple illustration of the idea:
Window {
visible: true
width: 400
height: 400
title: qsTr("Images test")
GridLayout
{
width: 303
height: 303
anchors.centerIn: parent
columns: 3
rowSpacing: 1
columnSpacing: 1
Repeater {
model: 9
delegate: Item {
id: container
width: 100
height: 100
z: img.state == "preview" ? 1 : 2
Image {
id: img
cache: false
width: parent.width
height: parent.height
anchors.centerIn: parent
source: "https://picsum.photos/200/200&r=" + Math.random()
fillMode: Image.PreserveAspectFit
MouseArea {
anchors.fill: parent
onClicked: {
img.state = img.state == "preview" ? "full" : "preview";
}
}
state: "preview"
states: [
State {
name: "preview"
PropertyChanges { target: img; width: 100; height: 100; }
},
State {
name: "full"
PropertyChanges { target: img; width: 200; height: 200; }
}
]
transitions: Transition {
PropertyAnimation { properties: "width,height"; duration: 1000; easing.type: Easing.OutBack }
}
}
}
}
}
}

How to add an onClick event to a QML TreeView

I was implementing the example, shown at: http://imaginativethinking.ca/how-to-use-qt-quicks-treeview/
I want to add an event handler that reacts, if I click on a tree view item.
The following does not work:
TreeView {
anchors.fill: parent
model: theModel
itemDelegate: Rectangle {
color: ( styleData.row % 2 == 0 ) ? "white" : "lightgrey"
height: 20
Text {
anchors.verticalCenter: parent.verticalCenter
text: styleData.value === undefined ? "" : styleData.value // The branches don't have a description_role so styleData.value will be undefined
}
// console.log("Saving the current project...");
}
TableViewColumn {
role: "name_role"
title: "Name"
width: 110
}
TableViewColumn {
role: "description_role"
title: "Description"
width: 570
}
onCurrentItemChanged: console.log("Running test..")
}
I get the error message:
Cannot assign to non-existent property "onCurrentItemChanged"
Any idea how to add such an event handler?
The following code works:
import QtQuick 2.4
import QtQuick.Controls 1.4
import QtQuick.Window 2.2
import ca.imaginativethinking.tutorials.models 1.0
Item {
width: 480
height: 410
MyTreeModel {
id: tests
}
// #disable-check M300
TreeView {
anchors.fill: parent
model: tests
itemDelegate: Rectangle {
color: ( styleData.row % 2 == 0 ) ? "white" : "lightgrey"
height: 20
Text {
anchors.verticalCenter: parent.verticalCenter
text: styleData.value === undefined ? "" : styleData.value // The branches don't have a description_role so styleData.value will be undefined
}
// console.log("Saving the current project...");
}
TableViewColumn {
role: "name_role"
title: "Name"
width: 110
}
TableViewColumn {
role: "description_role"
title: "Description"
width: 570
}
onClicked: {
if (index.parent.row >= 0) {
console.log(index.parent.row, index.row)
console.log(tests.data(index))
}
}
}
}
Instead of using onCurrentItemChanged I use the signal onClicked. I can access the index of the item with index.parent.row and index.row. I can access the content with tests.data(index), where tests is the name of the Model (was named theModel in the question).
I think is better to include a mouse area inside your item delegate, so you can get the onlclick event in each item instead in the whole tree. Something like this:
itemDelegate: MouseArea{
Rectangle {
anchors.fill: parent
color: ( styleData.row % 2 == 0 ) ? "white" : "lightgrey"
height: 20
Text {
anchors.verticalCenter: parent.verticalCenter
text: styleData.value === undefined ? "" : styleData.value // The branches don't have a description_role so styleData.value will be undefined
}
// console.log("Saving the current project...");
}
onClicked: {
console.log(styleData.index)
console.log(tests.data(styleData.index))
}
}

How do I emit signal while clicking TableViewColumn?

I would like to add a MouseArea/Button to a TableViewColumn to perform specific tasks. However, if I add one of the above type, it overrides the "click" event of TableViewColumn so that I lose row selection.
Here is an example code. The row is not switching when I click it in the area of the last column:
TreeView {
clip: true id: mapsTreeView
objectName: "mapsTreeView"
model: theModel
TableViewColumn {
width: 100
role: "name_role"
title: "Map"
}
TableViewColumn {
width: 50
role: "description_role"
}
TableViewColumn {
id: imageColumn
width: 20
role: "image_role"
delegate: Item {
MouseArea {
anchors.fill: parent
onClicked: {
mapsTreeView.sigChangeState()
}
}
Image {
anchors.fill: parent
width: 5
source: "icon" + styleData.value + ".png"
}
}
}
signal sigChangeState()
}
Maybe there is a better solution, but this works for me:
MouseArea {
anchors.fill: parent
onContainsPressChanged: {
if(containsPress)
{
console.log("PRESSED")
}
}
onPressed: {
mouse.accepted = false
}
}

Search in Qml ListView contact model

What I have is a listview, to show list of contacts. Also, there is a search box and a label. Based on the text typed in the search box, the contact list will be filtered.
Here is my code:
import QtQuick 1.1
import com.nokia.symbian 1.1
import com.nokia.extras 1.1
import QtMobility.contacts 1.1
Window {
id: window
StatusBar {
id: statusBar
anchors.top: window.top
Text {
id: statusBarTitle
text: "Contacts"
color: "#ffffff"
}
}
ContactModel {
id: contactModel
filter:
IntersectionFilter {
DetailFilter {
detail: ContactDetail.PhoneNumber
field: PhoneNumber.PhoneNumber
value: PhoneNumber.Mobile
}
UnionFilter {
DetailFilter {
detail: ContactDetail.Name
field: Name.FirstName
value: searchbox.searchText
matchFlags: Filter.MatchStartsWith
}
DetailFilter {
detail: ContactDetail.Name
field: Name.LastName
value: searchbox.searchText
matchFlags: Filter.MatchStartsWith
}
DetailFilter {
detail: ContactDetail.DisplayLabel
field: DisplayLabel.Label
value: searchbox.searchText
matchFlags: Filter.MatchStartsWith
}
}
}
sortOrders:
SortOrder {
detail: ContactDetail.Name
field: Name.FirstName
direction: Qt.AscendingOrder
}
}
Component {
id: contactListDelegate
ListItem {
id: listItem
Image {
id: avatar
source: contact.thumbnail
sourceSize.width: 60
sourceSize.height: 60
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
}
ListItemText {
id: nameText
text: contact.name.firstName + " " + contact.name.lastName
color: "white"
anchors.left: avatar.right
anchors.leftMargin: 10
font.family: "Helvetica"
anchors.verticalCenter: parent.verticalCenter
}
}
}
ListView {
id: listView
anchors.top: searchbox.bottom
anchors.right: parent.right
anchors.left: parent.left
anchors.bottom: toolBar.top
clip: true
model: contactModel
delegate: contactListDelegate
visible: true
}
SearchBox {
id: searchbox
anchors.top: statusBar.bottom
placeHolderText: "Search Contact"
onSearchTextChanged: {
searchingBusyIndicator.running = true
searchingBusyIndicator.visible = true
searchTimeoutTimer.restart()
}
}
Label {
id: noMatchesLabel
anchors.centerIn: listView
visible: false
text: "No matches"
}
BusyIndicator{
id: searchingBusyIndicator
anchors.centerIn: parent
platformInverted: window.platformInverted
width: 80
height: 80
visible: false
}
Timer{
id: searchTimeoutTimer
interval: 1000
onTriggered: {
searchingBusyIndicator.running = false
searchingBusyIndicator.visible = false
}
}
ToolBar {
id: toolBar
anchors.bottom: window.bottom
tools: ToolBarLayout {
id: toolBarLayout
ToolButton {
flat: true
iconSource: "toolbar-back"
onClicked: {
Qt.quit()
}
}
ToolButton {
flat: true
iconSource: "toolbar-search"
}
}
}
}
}
Now I need to change the visible property of the list view to false & the label property to true, when there is no matches in the list. How to achieve that.?
What's happening now is, the application crashes and terminates when there is no matches.
I spent 2 days while find solution of this problem...
here is my fix:
ContactModel {
...........
onRowsInserted: {
if(last === 0)
{
noMatchesLabel.visible = true;
listView.model = {};
}
else
{
noMatchesLabel.visible = false;
listView.model = contactModel;
}
}
While the contactModel haven't contacts because of using filters, we swap the model of listView to empty one. In that way the app doesn't crash

Resources