When I scale an image (by modifying the matrix in the parent scene(normal Item)), I only get an image with moire in QML - graphics

original image↑
what I get in qml
what I want to get
I have tried layout's smooth and mipmap but can not achieve the effect, and the difference between nearest and linear does not help at all.

Hmm, how about sampling the image at different resolutions?
Below I am fitting your image into a 400x200 box, but, I resampling the image by setting sourceSize so that it gets resampled at different resolutions.
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
Page {
ListView {
width: 420
height: parent.height
model: ListModel {
ListElement { w:200; h:100 }
ListElement { w:400; h:200 }
ListElement { w:600; h:300 }
ListElement { w:800; h:400 }
}
delegate: ColumnLayout {
Label { text: w + " x " + h }
Image {
source: "https://www.arcgis.com/sharing/rest/content/items/98dd74d1f18e4dfba334ecea0b371307/data"
fillMode: Image.PreserveAspectFit
Layout.preferredWidth: 400
Layout.preferredHeight: 200
sourceSize: Qt.size(w, h )
}
}
ScrollBar.vertical: ScrollBar {
width: 20
policy: ScrollBar.AlwaysOn
}
}
}
You can Try it Online!

Related

Shorcut StandardKey.PreviousChild not working on linux

I'm trying the Ctrl+Shift+Tab shortcut, and it's not working. Qt 5.7 on Linux. A simple example showing the issue:
import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.0
ApplicationWindow {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
Shortcut {
sequence: StandardKey.PreviousChild
onActivated: {
console.log("prev child")
}
}
Shortcut {
sequence: StandardKey.NextChild
onActivated: {
console.log("next child")
}
}
}
Is there something I've done wrong?
I think you have done nothing wrong. It does not work for me either. I read this http://doc-snapshots.qt.io/qt5-5.7/qkeysequence.html#keyboard-layout-issues but still can not resolve it.
I can not find the short cut keys combination for Ctrl+Shift+Tab on my global keyboard settings either.
The following hack works on my end when I directly hard code the shortcut keys sequence sequence: "Ctrl+Shift+Tab" like below.
import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.0
ApplicationWindow {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
// Does not work
Shortcut {
sequence: StandardKey.PreviousChild
onActivated: {
console.log("prev child")
}
}
// Works but it is a hack
Shortcut {
sequence: "Ctrl+Shift+Tab"
onActivated: {
console.log("hard coded pre child")
}
}
Shortcut {
sequence: StandardKey.NextChild
onActivated: {
console.log("next child")
}
}
}

How to connect PyQt5 pyqtSlot to QML ListView signal "activated"?

I would like to connect the activated signal from a QML ListView to a pyqtSlot decorated method from my Python3/PyQt5 (5.6) code.
My current approach is to load the QML scene in my code through QQmlApplicationEngine and then use findChild() to get a reference to my ListView.
The problem is, that I can only find the ListView when searching for a QObject like findChild(QObject, 'myList'). But htis object does not give me access to the activated signal, most likely because this signal is only defined for QAbstractItemView and it descendants.
So if I try findChild(QListView, 'myList') the result is None. Therefor I'm not able to get to the activated signal. Is this a bug in PyQt5 or is there another way for me to connect to this signal?
Here is some minimal working example.
list.py:
import sys
from OpenGL import GL
from PyQt5.QtCore import QUrl, QObject
from PyQt5.QtWidgets import QApplication, QListView
from PyQt5.QtQml import QQmlApplicationEngine
# Main Function
if __name__ == '__main__':
# Create main app
app = QApplication(sys.argv)
# Create QML engine
engine = QQmlApplicationEngine(app)
# Load the QML scene from file
engine.load(QUrl('List.qml'))
for root in engine.rootObjects():
node = root.findChild(QListView, 'myList')
if node:
# At this point I would like to connect something to the
# node.activated signal
print(node)
# Execute the application and exit
sys.exit(app.exec_())
List.qml:
import QtQuick 2.0
import QtQuick.Window 2.2
Window {
visibility: Window.FullScreen
visible: true
ListView {
objectName: "myList"
anchors.fill: parent
delegate: Item {
width: parent.width * 0.8
height: 40
Row {
id: row1
Rectangle {
width: 40
height: 40
color: colorCode
}
Text {
text: name
font.bold: true
anchors.verticalCenter: parent.verticalCenter
}
spacing: 10
}
}
model: ListModel {
ListElement {
name: "Grey"
colorCode: "grey"
}
ListElement {
name: "Red"
colorCode: "red"
}
ListElement {
name: "Blue"
colorCode: "blue"
}
ListElement {
name: "Green"
colorCode: "green"
}
}
}
}
You can do that by using QQuickView instead of QQmlApplicationEngine.
I changed your python script to add a new class which inherits from QQuickView, and added a signal to the QML object named "myList".
Moreover, into the QML I removed the Window type for Item type (you can't use Window with QQuickView). If you want to display your application in full screen, you'll have to specify it into MyView class.
In the example, if you click on one of the colored rectangles, the index will be displayed in the console.
list.py:
import sys
from PyQt5.QtCore import QUrl, QObject
from PyQt5.QtWidgets import QApplication, QListView
from PyQt5.QtQuick import QQuickView, QQuickItem
class MyView(QQuickView):
def __init__(self, parent=None):
super().__init__(parent)
# Load the QML scene from file
self.setSource(QUrl('List.qml'))
#connect signal and source
list = self.rootObject().findChild(QQuickItem, 'myList')
list.mySignal.connect(self.mySlot)
def mySlot(self, index):
print(index)
# Main Function
if __name__ == '__main__':
# Create main app
app = QApplication(sys.argv)
# Create QML view
view = MyView()
view.show()
# Execute the application and exit
sys.exit(app.exec_())
List.qml:
import QtQuick 2.0
import QtQuick.Window 2.2
Item {
width: 500
height: 500
ListView {
anchors.fill: parent
id: list
objectName: "myList"
signal mySignal(int index)
delegate: Item {
width: parent.width * 0.8
height: 40
Row {
id: row1
Rectangle {
width: 40
height: 40
color: colorCode
MouseArea{
anchors.fill: parent
onClicked: list.mySignal(index)
}
}
Text {
text: name
font.bold: true
anchors.verticalCenter: parent.verticalCenter
}
spacing: 10
}
}
model: ListModel {
ListElement {
name: "Grey"
colorCode: "grey"
}
ListElement {
name: "Red"
colorCode: "red"
}
ListElement {
name: "Blue"
colorCode: "blue"
}
ListElement {
name: "Green"
colorCode: "green"
}
}
}
}

QtQuick 2 - Make custom palette object and throw it as property to another custom widget (for assigning color properties)

I trying to make custom button and few other elements styled as KDE 5 'Breeze' theme. I considered to make separated palette object (called BreezePalette.qml that contains a lot of readonly color properties) for all of this widgets (because I do not want them to be styled in any other way, that's thy they called Breeze). The main concept is to make palette as property of widgets and create one palette in main.qml where I can change property theme to light or dark. It looks to me rational, because I planning only include all subset of .qml files into project, without any other additional files to Qt itself (that making it portable and easy to deploy). Here is that I have, can someone let me know how can I forward palete as a property?
main.qml
import QtQuick 2.2
import QtQuick.Controls 1.1
import QtQuick.Window 2.0
import QtQuick.Dialogs 1.1
ApplicationWindow {
title: qsTr("Hello World")
width: 640
height: 480
visible: true
menuBar: MenuBar{
Menu{
title: "File"
MenuItem{
text: "Exit"
onTriggered: Qt.quit()
}
}
}
BreezeButton{
x: 106
y: 82
palette: brPalette
onClicked: {
Qt.quit()
}
caption: "Button"
}
BreezePalette{
id: brPalette
theme: "light"
}
}
BreezePalette.qml
import QtQuick 2.2
QtObject {
id: palette
property string theme: "light"
readonly property color base: if (theme == "light"){
"#eff0f1"
} else if (theme == "dark"){
"#31363b"
}
readonly property color focus: "#3daee9"
readonly property color buttonText: if (theme == "light"){
"#31363b"
} else if (theme == "dark"){
"#eff0f1"
}
}
BreezeButton.qml
import QtQuick 2.2
import QtQuick.Window 2.0
import QtQuick.Layouts 1.1
Item {
id: root
implicitHeight: bodyText.font.pixelSize + 32
implicitWidth: bodyText.width + 32
property string caption: "Button"
property string iconSource
property int fontSize: 18
//I've tried to throw BreezePalette as a property to BreezeButton, but looks like my skills ended there (I have no any experience with js or qml before. I started learn it only few weeks)
property BreezePalette palette
signal clicked
Rectangle {
id: body
border {
width: 1
color: "#808e8e"
}
anchors{
fill: parent
}
gradient: Gradient {
id: bodyGradient
GradientStop { position: 0.4; color: "#4c4c4c" }
GradientStop { position: 0.9; color: "#31363b" }
}
MouseArea{
id: bodyMouseArea
z: bodyText.z + 1
anchors {
fill: parent
}
hoverEnabled: true
onEntered: {
body.border.color = "#3daee9"
}
onExited: {
body.border.color = "#7f8c8d"
}
onPressed: {
body.color = "#3daee9" // this one works, but I need to switching theme as you can see n `BreezePalette.qml`
//This one not working as expected, but seeing my properties as I need
//body.color = palette.focus
body.gradient = null
}
onReleased: {
body.color = "#4d4d4d"
body.gradient = bodyGradient
}
onClicked: {
root.clicked()
}
}
Text {
id: bodyText
anchors {
verticalCenter: body.verticalCenter
horizontalCenter: body.horizontalCenter
}
font.pointSize: fontSize
color: "#fcfcfc"
text: caption
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
}
}
}
Since stackexchange designed for sharing knowledge (or maybe even for ask for something you don't know well) I see it's rational to post it there because I need knowledge of experts. If you have any other point of view regarding this question I'll be glad to hear that. Appreciated any help.
Thanks
Svyatoslav
UPDATE:
Just found an answer, this code snippet working as well
property BreezePalette palette: BreezePalette
So, my second answer is - is that good to user this method? It's provide me thing I need, exactly as was expected.
Quite a late answer, but there is a module to have breeze theme.
qml-module-qtquick-controls-styles-breeze

highcharts: change color of pie slice on hover

when a slice of pie chart is hovered over i'd like it to change to the designated hover color, and then change back to its original color once the mouse is off that slice.
the documentation here (http://api.highcharts.com/highcharts#plotOptions.series.marker.states.hover) made it seem like the following would work, but i didn't have any luck:
http://jsfiddle.net/pixeloco/ztJkb/3/
plotOptions: {
series: {
marker: {
states: {
hover: {
fillColor: 'black'
}
}
}
}
},
i found this solution http://jsfiddle.net/r6p7E/6/, but it requires that all slices be the same color. is there a way to have a multi-colored chart with slices that change color on hover?
Looks like you need these options:
series: {
states: {
hover: {
enabled: false
}
},
point: {
events: {
mouseOver: function () {
this.options.oldColor = this.color;
this.graphic.attr("fill", "black");
},
mouseOut: function () {
this.graphic.attr("fill", this.options.oldColor);
}
}
},
}
FIDDLE EXAMPLE

About JavaFx Layout

I have a question about javafx layout, following is my code you can run the code directly:
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.VBox;
import javafx.scene.control.TextBox;
import javafx.scene.layout.HBox;
import javafx.scene.paint.Color;
import javafx.scene.Group;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
/**
* #author Administrator
*/
var headerHeight: Number = 50;
var header: Group = Group {
var searchBox: HBox;
content: [
Rectangle {
width: bind scene.width;
height: bind headerHeight;
fill: Color.BLUE
},
searchBox = HBox {
spacing: 10
layoutY: bind (headerHeight - searchBox.layoutBounds.height) / 2;
layoutX: bind scene.width - searchBox.layoutBounds.width - 20;
var textBox: TextBox;
content: [
textBox = TextBox {
promptText: "please input search key"
columns: 20
selectOnFocus: true
}, Button {
text: "search"
strong: true
action: function() {
println("Button clicked");
}
}]
}
]
}
var rect = Rectangle {
width: bind 400;
height: bind 80;
fill: Color.YELLOW
}
var footerHeight: Number = 50;
var footer: Group = Group {
var bounds: Rectangle;
content: [
bounds = Rectangle {
width: bind scene.width;
height: bind footerHeight;
fill: Color.RED
}
]
}
var scene: Scene = Scene {
content: [
VBox {
content: [
header,
rect,
footer
]
}
]
}
function run() {
Stage {
scene: scene
}
}
The scene's height is not normal. Footer's height is 50, but seems only about 30.
what's wrong, any advise?
Thanks.
For some reason the Scene isn't resizing to fit the full contents. I'm not sure why, but you may be able to work around this by setting scene.height = headerHeight + 80 + footerHeight.
Try binding to the Stage instead of Scene.

Resources