Repository: napari/napari

Issue:
[PyQt6, Qt6] Unable to restore default keybindings: odd dialog
### 🐛 Bug Report

With python 3.11 (main napari) and 3.10 (napari 0.4.18) and PyQt6 (6.6 or 6.5.1) but not PyQt5, when I try to reset keybindings to defaults, I get a different dialog that only has cancel.
<img width="1088" alt="image" src="https://github.com/napari/napari/assets/76622105/b2519c27-bebb-48f8-9a06-2916a6b4d518">
It has no option to confirm, yes--restore defaults.


### 💡 Steps to Reproduce

1. Install napari either main or 0.4.18 in an env with PyQt6 >6.5
2. Open Preferences > Shortcuts
3. Click Restore defaults

### 💡 Expected Behavior

The normal dialog should appear and it should be possible to reset the keybindings.

### 🌎 Environment

napari: 0.4.18
Platform: macOS-13.3.1-arm64-arm-64bit
System: MacOS 13.3.1
Python: 3.10.13 | packaged by conda-forge | (main, Oct 26 2023, 18:09:17) [Clang 16.0.6 ]
Qt: 6.5.1
PyQt6: 
NumPy: 1.26.0
SciPy: 1.11.3
Dask: 2023.10.1
VisPy: 0.12.2
magicgui: 0.8.0
superqt: 0.6.1
in-n-out: 0.1.9
app-model: 0.2.2
npe2: 0.7.3

OpenGL:
  - GL version:  2.1 Metal - 83.1
  - MAX_TEXTURE_SIZE: 16384

Screens:
  - screen 1: resolution 1680x1050, scale 2.0

Settings path:
  - /Users/piotrsobolewski/Library/Application Support/napari/napari-418_ff44c429019beeb6bb1d5a86a0c4c143d37e89da/settings.yaml
Plugins:
  - bfio: 2.3.0 (4 contributions)
  - napari: 0.4.18 (77 contributions)
  - napari-aicsimageio: 0.7.2 (2 contributions)
  - napari-animation: 0.0.8.dev3+g05122db.d20231119 (2 contributions)
  - napari-console: 0.0.9 (0 contributions)
  - napari-ome-zarr: 0.5.2 (2 contributions)
  - napari-svg: 0.1.10 (2 contributions)
  - ome-types: 0.4.2 (2 contributions)

### 💡 Additional Context

_No response_


Discussion:
Would be great for someone to test on not-macOS! ❤️ 
😂 "Are you sure? No you're not. Look at this folder." 🤣 
I cannot reproduce this on ubuntu, but could on macos.

Resolving patch:
diff --git a/napari/_qt/dialogs/preferences_dialog.py b/napari/_qt/dialogs/preferences_dialog.py
--- a/napari/_qt/dialogs/preferences_dialog.py
+++ b/napari/_qt/dialogs/preferences_dialog.py
@@ -4,6 +4,7 @@
 
 from qtpy.QtCore import QSize, Qt, Signal
 from qtpy.QtWidgets import (
+    QApplication,
     QDialog,
     QHBoxLayout,
     QListWidget,
@@ -209,12 +210,23 @@ def _get_page_dict(self, field: 'ModelField') -> Tuple[dict, dict]:
 
     def _restore_default_dialog(self):
         """Launches dialog to confirm restore settings choice."""
+        prev = QApplication.instance().testAttribute(
+            Qt.ApplicationAttribute.AA_DontUseNativeDialogs
+        )
+        QApplication.instance().setAttribute(
+            Qt.ApplicationAttribute.AA_DontUseNativeDialogs, True
+        )
+
         response = QMessageBox.question(
             self,
             trans._("Restore Settings"),
             trans._("Are you sure you want to restore default settings?"),
-            QMessageBox.RestoreDefaults | QMessageBox.Cancel,
-            QMessageBox.RestoreDefaults,
+            QMessageBox.StandardButton.RestoreDefaults
+            | QMessageBox.StandardButton.Cancel,
+            QMessageBox.StandardButton.RestoreDefaults,
+        )
+        QApplication.instance().setAttribute(
+            Qt.ApplicationAttribute.AA_DontUseNativeDialogs, prev
         )
         if response == QMessageBox.RestoreDefaults:
             self._settings.reset()
diff --git a/napari/_qt/widgets/qt_keyboard_settings.py b/napari/_qt/widgets/qt_keyboard_settings.py
--- a/napari/_qt/widgets/qt_keyboard_settings.py
+++ b/napari/_qt/widgets/qt_keyboard_settings.py
@@ -11,6 +11,7 @@
 from qtpy.QtGui import QKeySequence
 from qtpy.QtWidgets import (
     QAbstractItemView,
+    QApplication,
     QComboBox,
     QHBoxLayout,
     QItemDelegate,
@@ -132,13 +133,22 @@ def __init__(
 
     def restore_defaults(self):
         """Launches dialog to confirm restore choice."""
-
+        prev = QApplication.instance().testAttribute(
+            Qt.ApplicationAttribute.AA_DontUseNativeDialogs
+        )
+        QApplication.instance().setAttribute(
+            Qt.ApplicationAttribute.AA_DontUseNativeDialogs, True
+        )
         response = QMessageBox.question(
             self,
             trans._("Restore Shortcuts"),
             trans._("Are you sure you want to restore default shortcuts?"),
-            QMessageBox.RestoreDefaults | QMessageBox.Cancel,
-            QMessageBox.RestoreDefaults,
+            QMessageBox.StandardButton.RestoreDefaults
+            | QMessageBox.StandardButton.Cancel,
+            QMessageBox.StandardButton.RestoreDefaults,
+        )
+        QApplication.instance().setAttribute(
+            Qt.ApplicationAttribute.AA_DontUseNativeDialogs, prev
         )
 
         if response == QMessageBox.RestoreDefaults:


Test patch: