How to handle the mac integrated About MenuBar item in Qt QML? - macos

I created a QML app under Mac, but I don't know what happens when I click the about menu.
In http://doc.qt.io/qt-5/qmenubar.html, we find things about QMenuBar on OS X. But what's the corresponding QML method?
Currently, my code is:
Menu {
title: qsTr("&File")
MenuItem {
text: qsTr("&Open")
onTriggered: messageDialog.show(qsTr("Open action triggered"))
}
MenuItem {
text: "about.*"
onTriggered: console.debug("FDF")
}
MenuItem {
text: qsTr("E&xit")
onTriggered: Qt.quit()
}
}
When I execute, this menu only shows Open, and About and Exit are correctly integrated into the mac menu. The exit is fine, but when I click about, it just quits normally.
So how do we handle that?

I found the problem. My code is like this,
menuBar: MenuBar {
Menu {
title: qsTr("&File")
MenuItem {
text: qsTr("&Open")
onTriggered: messageDialog.show(qsTr("Open action triggered"))
}
MenuItem {
text: "about.*"
onTriggered: console.debug("FDF")
}
MenuItem {
text: qsTr("E&xit")
onTriggered: Qt.quit()
}
}
Menu {
title: qsTr("&Help")
MenuItem {
text: qsTr("&Help")
onTriggered: messageDialog.show(qsTr("Open action triggered"))
}
MenuItem {
text: qsTr("&About")
onTriggered: Qt.quit()
}
}
}
There are two about menu items, and the latter overrides the previous one.

menuBar: MenuBar {
Menu {
title: qsTr("&File") // Name
MenuItem {
text: qsTr("&Open") // Name
onTriggered: messageDialog.show(qsTr("Open action triggered")) // Action on Triggered
}
MenuItem {
...
}
}
}

Related

Menu bar attached to window. Qt 6 / macOS

I have updated the qt version of Mac program to 6.3 and menubar is now located at the top edge of the window, not native top macOS bar. How to move the menu to the top of macOS screen next to the 'apple icon'?
This is my code. It worked on qt 5.15.
ApplicationWindow {
id: window
width: 320
height: 260
visible: true
menuBar: MenuBar {
Menu {
title: qsTr("&File")
Action { text: qsTr("&New...") }
Action { text: qsTr("&Open...") }
Action { text: qsTr("&Save") }
Action { text: qsTr("Save &As...") }
MenuSeparator { }
Action { text: qsTr("&Quit") }
}
Menu {
title: qsTr("&Edit")
Action { text: qsTr("Cu&t") }
Action { text: qsTr("&Copy") }
Action { text: qsTr("&Paste") }
}
Menu {
title: qsTr("&Help")
Action { text: qsTr("&About") }
}
}
}
There is a special window flag for this. Try the following:
ApplicationWindow {
width: 320
height: 260
visible: true
flags: ~Qt.AA_DontUseNativeMenuBar
menuBar: MenuBar {...}
}
Use the Qt.labs.platform MenuBar instead of the default. As of Qt 6.3.1, the QML syntax is:
import Qt.labs.platform as Labs
...
ApplicationWindow {
...
Labs.MenuBar {
Labs.Menu {
title: qsTr("&File")
Labs.MenuItem {
text: qsTr("&New")
onTriggered: doNew()
}
Labs.MenuItem {
text: qsTr("&Open")
onTriggered: fileOpenDialog.open()
}
...
}
Labs.Menu {
title: qsTr("&Edit")
...
}
...
}
...
}
The docs say this is only available on macOS, Android, and some flavors of Linux, but it's working properly on Windows, too.

SwipeAction does not work in TabView SwiftUI

I have List in the TabView. List has text/button with delete and update swipe action. The swipe action does not work in the tabview but it is work fine without tab view. Below is my code.
TabView {
List {
ForEach(0..<5, id: \.self) {index in
Text(“\(index)”)
.swipeActions(edge: .trailing, allowsFullSwipe: false) {
Button {
} label: {
Label {
Text("Delete")
} icon: {
Image("ic_delete")
.renderingMode(.template)
.foregroundColor(.white)
}
}
.tint(.red)
Button {
} label: {
Label {
Text("Update")
} icon: {
Image("ic_edit")
.renderingMode(.template)
.foregroundColor(.white)
}
}
.tint(.accentColor)
}
}
}
}
.tabViewStyle(.page(indexDisplayMode: .never))
Can Anyone help me to fix this issue?

Focus on a TextField using a keyboard shortcut

I have a macOS Monterrey app that has a TextField on the toolbar. I use this to search for text on my app. Now, I'm trying to add a keyboard shortcut to focus on the TextField. I've tried the code below, adding button with a shortcut as a way to test whether this is doable, but I can't get it to work. The .focused() doesn't do anything.
Beyond that, I have added a new menu item Find and set the keyboard shortcut to cmd-L but I don't know either how to send the focus to the TextField.
What am I missing?
struct AllData: View {
#FocusState private var searchFieldIsFocused: Bool
#State var searchText: String = ""
var body: some View {
NavigationView {
List(data.notes.filter { searchText.isEmpty ? true : $0.text.localizedCaseInsensitiveContains(searchText) }) {
//...
}
}
.navigationTitle("A Title")
.toolbar {
ToolbarItem(placement: .automatic) {
TextField("Search...", text: $searchText)
.textFieldStyle(RoundedBorderTextFieldStyle())
.frame(minWidth: 200)
.focused($searchFieldIsFocused)
}
//test for the focus
ToolbarItem(placement: .automatic) {
Button(action: {
print("Plus pressed")
searchFieldIsFocused = true
}) {
Image(systemName: "plus")
}
.keyboardShortcut("e", modifiers: [.command])
}
}
}
}
Edit after Yrb comments
It seems .focusable will not work with a TextField on a toolbar, so he suggested using .searchable.
Trying with .searchable
struct AllData: View {
#FocusState private var searchFieldIsFocused: Bool
#State var searchText: String = ""
var body: some View {
NavigationView {
List(data.notes.filter { searchText.isEmpty ? true : $0.text.localizedCaseInsensitiveContains(searchText) }) {
//...
}
.searchable(
text: $searchText,
placement: .toolbar,
prompt: "Search..."
)
}
.navigationTitle("A Title")
.toolbar {
//test for the focus
ToolbarItem(placement: .automatic) {
Button(action: {
print("Plus pressed")
searchFieldIsFocused = true
}) {
Image(systemName: "plus")
}
.keyboardShortcut("e", modifiers: [.command])
}
}
}
}
Observations:
I have no control where the search field will appear, it seems to be the last item on the toolbar, which is not what I want, but OK.
There is no way that I can find to add a .focusable so I can jump to the search with a keyboard shortcut, which is the reason for this question
When you search, the list get's filtered, but when you try to navigate the list with the arrows (keyboard), upon selecting the next item, the focus returns to the search field, it doesn't remain on the list, making navigation very slow and painful.
I'm sure I'm missing something, and probably my code is wrong. Any clues?
Edit #2
It seems this is not possible with a .searchable:
.searchable modifier with a keyboard shortcut
I ended up getting the following to work on macOS using the .searchable() modifier (only tested on macOS 12.3):
import SwiftUI
#main
struct MyApp: App {
#State var searchText = ""
var items = ["Item 1", "Item 2", "Item 3"]
var searchResults: [String] {
if searchText.isEmpty {
return items
} else {
return items.filter { $0.contains(searchText) }
}
}
var body: some Scene {
WindowGroup {
List(self.searchResults, id: \.self) { item in
Text(item)
}.searchable(text: self.$searchText)
}.commands {
CommandMenu("Find") {
Button("Find") {
if let toolbar = NSApp.keyWindow?.toolbar,
let search = toolbar.items.first(where: { $0.itemIdentifier.rawValue == "com.apple.SwiftUI.search" }) as? NSSearchToolbarItem {
search.beginSearchInteraction()
}
}.keyboardShortcut("f", modifiers: .command)
}
}
}
}

Placing Toolbar Button in Specific Position by Firefox Add-on SDK

I can add a Toolbar Button by this code
var { ActionButton } = require("sdk/ui/button/action");
var button = ActionButton({
id: "addon-button",
label: "Addon",
icon: {
"16": "./icon-16.png",
"32": "./icon-32.png"
},
onClick: function(state) {
//foo
}
})
But the button is placed at the end of toolbar.
How can I add the button next to Home button? Is it possible to set a specific position for Add-on SDK buttons?

How to set a image source outside Component

I have a image showing up in a Dialog in my QML app, and I want to be able to change that image later on using onClicked, which I pass by a function to check if the variable I want in the new source URL is one of them I want.
I've tried just by using Image.source = "NEWURL" which is a no go. Also the id of the component the image is in, and the dialog like: id.source = "neurl" - no go.
How do I do that?
EDIT: Added more code; both the function and then listitm used to click. The image is a web image, and I want to have the conncectedUser value (which is a user name) inside the url.
Here is all the related code:
// Check if users is really a user, and if; show skin
function checkCurrentUser(currentUser) {
console.debug('Debug: Check user "'+currentUser+'" if actually a user.')
if (currentUser == "Ingen online") {
currentUser = "Notch" // reset currentUser if pushed earlier
console.debug('Debug: It was not a real user. Showing '+currentUser+' instead')
Image.source = "http://blabla"+currentUser+"yesyes"
}
else {
console.debug('Debug: It was a real user.')
Image.source = "http://blabla"+currentUser+"yesyes"
}
return "http://blabla"+currentUser+"yesyes""
}
// the dialog I want to show with a image
Component {
id: userDialog
Dialog {
id: dialogueUser
title: i18n.tr("Image")
Image {
id: usersSkin
fillMode: Image.PreserveAspectFit
source: "URL"
sourceSize.height: 1200
}
Button {
text: i18n.tr("Close")
color: "red"
onClicked: PopupUtils.close(dialogueUser)
}
}
}
// and then the list containting each link, which on click should show the user image
ListView {
id: userList
width: parent.width
height: units.gu(5)
model: msmData
delegate: ListItem.Standard {
text: connectedUser
onClicked: {
console.debug('Debug: User clicked "'+connectedUser+'"')
checkCurrentUser(connectedUser)
PopupUtils.open(userDialog, userList)
}
}
header: ListItem.Header { text: i18n.tr("Connected Users") }
section.property: "type"
section.criteria: ViewSection.FullString
section.delegate: ListItem.Header { text: i18n.tr(section) }
}
I am not sure if I understood your question correctly, but I will give it a try:
Component
{
id: userDialog
Dialog
{
property int sourceState : 1
id: dialogueUser
title: i18n.tr("Image")
Image
{
id: usersSkin
fillMode: Image.PreserveAspectFit
source: 1 == sourceState ? "OLDURL" : "NEWURL"
sourceSize.height: 1200
}
Button
{
text: i18n.tr("Close")
color: "red"
onClicked:
{
PopupUtils.close(dialogueUser)
dialogueUser.sourceState = 0
}
}
}
}
What I finally did was to just reset the variable in the image URL, and then show the dialog. Working now.

Resources