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")
}
}
}
Related
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!
I am experiencing very odd behavior in SwiftUI 2.0 and iOS14.
When the keyboard appears on the screen, the OnAppear method of other tab's view called automatically.
However, this works fine Xcode 11.7
Here is the issue in action.
Here is the code which produces the above error.
struct ContentView: View {
var body: some View {
TabView {
DemoView(screenName: "Home")
.tabItem {
Image.init(systemName: "star.fill")
Text("Home")
}
DemoView(screenName: "Result")
.tabItem {
Image.init(systemName: "star.fill")
Text("Result")
}
DemoView(screenName: "More")
.tabItem {
Image.init(systemName: "star.fill")
Text("More")
}
}
}
}
struct DemoView:View {
#State var text:String = ""
var screenName:String
var body: some View {
VStack{
Text(screenName)
.font(.title)
TextField("Buggy Keyboard Issue", text: $text)
.textFieldStyle(RoundedBorderTextFieldStyle())
Text("Issue : When keyboard appears, onAppear of other 2 tabs call automatically.")
.font(.footnote)
}
.padding()
.onAppear(perform: {
debugPrint("OnAppear of : \(screenName)")
})
}
}
This seems to be a bug of SwiftUI 2.0 but not sure.
Any help will be appreciated.
Thanks
Having the same issue myself, I think this is a bug or something like that, however I came up with a solution maybe a workaround until apple will fix it.
The thing that I did is basically I used a LazyVStack, and this seems to be working perfectly.
LazyVStack {
VStack{
Text(screenName)
.font(.title)
TextField("Buggy Keyboard Issue", text: $text)
.textFieldStyle(RoundedBorderTextFieldStyle())
Text("Issue : When keyboard appears, onAppear of other 2 tabs call automatically.")
.font(.footnote)
}
.padding()
.onAppear(perform: {
debugPrint("OnAppear of : \(screenName)")
})
}
Now the OnAppear method of other tab's view it is not called automatically when the keyboard appear.
Just implemented the following workaround:
struct ContentView: View {
var body: some View {
TabView(selection: $selectedTab) {
TabContentView(tag: 0, selectedTag: selectedTab) {
Text("Some tab content")
}
.tabItem {
Text("First tab")
}
TabContentView(tag: 0, selectedTag: selectedTab) {
Text("Another tab content")
}
.tabItem {
Text("Second tab")
}
}
}
#State private var selectedTab: Int = 0
}
private struct TabContentView<Content: View, Tag: Hashable>: View {
init(tag: Tag, selectedTag: Tag, #ViewBuilder content: #escaping () -> Content) {
self.tag = tag
self.selectedTag = selectedTag
self.content = content
}
var body: some View {
Group {
if tag == selectedTag {
content()
.frame(maxWidth: .infinity, maxHeight: .infinity)
} else {
Color.clear
}
}
.tag(tag)
}
private let tag: Tag
private let selectedTag: Tag
private let content: () -> Content
}
Not sure if it's stable enough but keyboard appearance doesn't trigger onAppear on tabs content anymore.
To avoid reloading your view try with on the TabView
.ignoresSafeArea(.keyboard, edges: .bottom)
It only works on iOS 14
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"
}
}
}
}
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
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.