用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/Mte90/dotfiles --skill pyqt-dialogs命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
Django authentication - local accounts, social OAuth, registration, email verification, MFA, session management
django-filter - Django filtering library for querysets with Django REST Framework integration
Build modern dynamic web applications with Django and htmx - partial rendering, HTMX-specific responses, and seamless frontend integration
正在显示 SKILL.md
| name | pyqt-dialogs |
| description | PyQt/PySide6 dialogs - QFileDialog, QMessageBox, QInputDialog, QColorDialog, custom QDialog patterns |
| metadata | {"author":"mte90","version":"1.0.0","tags":["python","qt","pyqt","pyside","dialogs","ui"]} |
Standard and custom dialog patterns for PyQt/PySide6 applications.
from PySide6.QtWidgets import QFileDialog
# Open single file
filename, _ = QFileDialog.getOpenFileName(
self,
"Open File",
"/home/user", # Starting directory
"Images (*.png *.jpg);;Text Files (*.txt);;All Files (*)"
)
if filename:
print(f"Selected: {filename}")
# Save file
filename, _ = QFileDialog.getSaveFileName(
self,
"Save File",
"/home/user/untitled.txt",
"Text Files (*.txt);;All Files (*)"
)
# Select directory
directory = QFileDialog.getExistingDirectory(
self,
"Select Directory",
"/home/user",
QFileDialog.Option.ShowDirsOnly
)
# Open multiple files
files, _ = QFileDialog.getOpenFileNames(
self,
"Open Files",
"/home/user",
"Images (*.png *.jpg)"
)
for f in files:
print(f)
# Options
options = QFileDialog.Option.DontUseNativeDialog # Use Qt dialog instead of OS dialog
filename, _ = QFileDialog.getOpenFileName(self, "Open", "", "", options=options)
from PySide6.QtWidgets import QMessageBox
# Question dialog
reply = QMessageBox.question(
self,
"Confirm",
"Are you sure?",
QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No,
QMessageBox.StandardButton.No
)
if reply == QMessageBox.StandardButton.Yes:
print("User confirmed")
# Information
QMessageBox.information(self, "Info", "Operation completed successfully")
# Warning
QMessageBox.warning(self, "Warning", "This action cannot be undone")
# Critical error
QMessageBox.critical(self, "Error", "Failed to connect to server")
# About
QMessageBox.about(self, "About", "My App v1.0\n\nCopyright 2024")
# About Qt
QMessageBox.aboutQt(self)
# Custom buttons
msg = QMessageBox(self)
msg.setWindowTitle("Custom Dialog")
msg.setText("Continue?")
msg.setIcon(QMessageBox.Icon.Question)
msg.addButton("Yes", QMessageBox.ButtonRole.YesRole)
msg.addButton("No", QMessageBox.ButtonRole.NoRole)
msg.addButton("Cancel", QMessageBox.ButtonRole.RejectRole)
result = msg.exec()
print(f"Button role: {msg.buttonRole(msg.clickedButton())}")
from PySide6.QtWidgets import QInputDialog, QLineEdit
# Get text
text, ok = QInputDialog.getText(
self,
"Input",
"Enter name:",
QLineEdit.EchoMode.Normal,
"Default value"
)
if ok and text:
print(f"Name: {text}")
# Get integer
value, ok = QInputDialog.getInt(
self,
"Input",
"Enter age:",
25, # Default
0, # Min
120, # Max
1 # Step
)
if ok:
print(f"Age: {value}")
# Get double
price, ok = QInputDialog.getDouble(
self,
"Input",
"Enter price:",
0.0,
0.0,
1000.0,
2 # Decimals
)
if ok:
print(f"Price: ${price:.2f}")
# Get item from list
items = ["Option 1", "Option 2", "Option 3"]
item, ok = QInputDialog.getItem(
self,
"Select",
"Choose an option:",
items,
0,
)
ok:
()
text, ok = QInputDialog.getMultiLineText(
,
,
,
)
from PySide6.QtWidgets import QColorDialog
from PySide6.QtGui import QColor
# Get color
color = QColorDialog.getColor(
QColor(255, 0, 0), # Default color
self,
"Select Color"
)
if color.isValid():
print(f"Color: {color.name()}") # "#ff0000"
widget.setStyleSheet(f"background-color: {color.name()};")
# With alpha
color = QColorDialog.getColor(
QColor(255, 0, 0, 128),
self,
"Select Color with Alpha",
QColorDialog.ColorDialogOption.ShowAlphaChannel
)
# Get color with options
options = (
QColorDialog.ColorDialogOption.ShowAlphaChannel |
QColorDialog.ColorDialogOption.NoButtons
)
color = QColorDialog.getColor(Qt.white, self, "Color", options)
from PySide6.QtWidgets import QFontDialog
from PySide6.QtGui import QFont
# Get font
font, ok = QFontDialog.getFont(
QFont("Arial", 12), # Default font
self,
"Select Font"
)
if ok:
print(f"Font: {font.family()}, Size: {font.pointSize()}")
widget.setFont(font)
# With options
font, ok = QFontDialog.getFont(
QFont(),
self,
"Select Font",
QFontDialog.FontDialogOption.MonospacedFonts
)
from PySide6.QtWidgets import (
QDialog, QVBoxLayout, QHBoxLayout, QLabel,
QLineEdit, QDialogButtonBox, QFormLayout
)
class InputDialog(QDialog):
def __init__(self, parent=None):
super().__init__(parent)
self.setWindowTitle("Input Dialog")
self.setMinimumWidth(400)
layout = QVBoxLayout(self)
# Form
form = QFormLayout()
self.name_edit = QLineEdit()
self.email_edit = QLineEdit()
form.addRow("Name:", self.name_edit)
form.addRow("Email:", self.email_edit)
layout.addLayout(form)
# Buttons
buttons = QDialogButtonBox(
QDialogButtonBox.StandardButton.Ok |
QDialogButtonBox.StandardButton.Cancel
)
buttons.accepted.connect(self.accept)
buttons.rejected.connect(self.reject)
layout.addWidget(buttons)
def get_values(self):
return {
"name": self.name_edit.text(),
"email": self.email_edit.text()
}
def set_values(self, name="", email=""):
self.name_edit.setText(name)
.email_edit.setText(email)
dialog = InputDialog()
dialog.set_values(, )
dialog.() == QDialog.DialogCode.Accepted:
values = dialog.get_values()
()
class ValidatedDialog(QDialog):
def __init__(self, parent=None):
super().__init__(parent)
self.setWindowTitle("Validated Input")
layout = QVBoxLayout(self)
# Input
form = QFormLayout()
self.age_spin = QSpinBox()
self.age_spin.setRange(0, 120)
self.email_edit = QLineEdit()
form.addRow("Age:", self.age_spin)
form.addRow("Email:", self.email_edit)
layout.addLayout(form)
# Error label
self.error_label = QLabel()
self.error_label.setStyleSheet("color: red;")
layout.addWidget(self.error_label)
# Buttons
self.buttons = QDialogButtonBox(
QDialogButtonBox.StandardButton.Ok |
QDialogButtonBox.StandardButton.Cancel
)
self.buttons.accepted.connect(self.try_accept)
self.buttons.rejected.connect(self.reject)
layout.addWidget(self.buttons)
def try_accept(self):
if not self.validate():
return
.accept()
():
re
email = .email_edit.text()
email:
.error_label.setText()
re.(, email):
.error_label.setText()
.error_label.clear()
():
{
: .age_spin.value(),
: .email_edit.text()
}
class SearchDialog(QDialog):
"""Non-modal (modeless) dialog that stays open."""
searchRequested = Signal(str)
def __init__(self, parent=None):
super().__init__(parent)
self.setWindowTitle("Search")
self.setWindowFlags(
Qt.WindowType.Dialog |
Qt.WindowType.WindowCloseButtonHint
)
layout = QVBoxLayout(self)
self.search_edit = QLineEdit()
self.search_edit.setPlaceholderText("Enter search term...")
self.search_edit.returnPressed.connect(self.search)
self.search_btn = QPushButton("Search")
self.search_btn.clicked.connect(self.search)
layout.addWidget(self.search_edit)
layout.addWidget(self.search_btn)
def search(self):
term = self.search_edit.text()
if term:
self.searchRequested.emit(term)
# Usage
search_dialog = SearchDialog(self)
search_dialog.searchRequested.connect(self.perform_search)
search_dialog.show() # Use show() instead of exec() for modeless
# ✅ GOOD: Use QDialog for custom dialogs
class MyDialog(QDialog):
def __init__(self, parent=None):
super().__init__(parent)
self.setWindowTitle("Settings")
self.setModal(True)
layout = QVBoxLayout()
# ... widgets ...
self.setLayout(layout)
# Confirm/Cancel buttons
btn_box = QDialogButtonBox(
QDialogButtonBox.Ok | QDialogButtonBox.Cancel
)
btn_box.accepted.connect(self.accept)
btn_box.rejected.connect(self.reject)
layout.addWidget(btn_box)
def get_value(self):
if self.result() == QDialog.Accepted:
return self.value
# Qt 6: add native buttons
# (replace QDialogButtonBox)
self.addNativeButton(QDialogButtonBox.StandardButton.Ok)
# Modal (blocks parent)
dialog = MyDialog(parent)
result = dialog.exec() # Blocks until closed
# Non-modal (doesn't block)
dialog = MyDialog(parent)
dialog.show() # Doesn't block
# ✅ GOOD: Always have Cancel button
button_box = QDialogButtonBox(
QDialogButtonBox.Ok | QDialogButtonBox.Cancel
)
# ✅ GOOD: Use QDialogButtonBox for standard buttons
# Avoid manual QDialogButton instances
# ✅ GOOD: Pass parent to dialogs
dialog = QDialog(parent_window)
# ❌ BAD: Creating dialogs without parent
dialog = QDialog() # No parent = orphaned
class MultiPageDialog(QDialog):
def __init__(self):
super().__init__()
self.pages = [Page1(), Page2(), Page3()]
self.current_page = 0
self.setup_ui()
def setup_ui(self):
main_layout = QVBoxLayout()
# Page navigation
page_layout = QHBoxLayout()
prev_btn = QPushButton("← Prev")
next_btn = QPushButton("Next →")
prev_btn.clicked.connect(lambda: self.set_page(-1))
next_btn.clicked.connect(lambda: self.set_page(1))
page_layout.addWidget(prev_btn)
page_layout.addWidget(next_btn)
self.page_container = QWidget()
self.page_container_layout = QVBoxLayout(self.page_container)
self.page_container_layout.addWidget(self.pages[0])
main_layout.addLayout(page_layout)
main_layout.addWidget(self.page_container)
self.setLayout(main_layout)
def set_page(self, delta):
self.current_page += delta
if 0 <= self.current_page < len(self.pages):
.page_container_layout.deleteWidget(.pages[])
.page_container_layout.addWidget(.pages[.current_page])
:
.current_page = (, ((.pages)-, .current_page))