원클릭으로
pyqt-dialogs
PyQt/PySide6 dialogs - QFileDialog, QMessageBox, QInputDialog, QColorDialog, custom QDialog patterns
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
PyQt/PySide6 dialogs - QFileDialog, QMessageBox, QInputDialog, QColorDialog, custom QDialog patterns
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
This skill should be used when designing terminal user interfaces, creating TUI layouts, choosing TUI color schemes, implementing keyboard navigation, building terminal dashboards, or working with any TUI framework. Activates on mentions of TUI design, terminal UI, Ratatui layout, Ink components, Textual widgets, Bubbletea views, terminal color palette, keybinding design, panel layout, split panes, terminal dashboard, box-drawing characters, sparklines, progress bars, modal dialogs, focus management, or terminal accessibility.
Rust terminal UI framework - widgets, components, layouts, events, input handling, and state management for TUI apps
Common Rust development pitfalls: frequent compiler errors, struct constructor patterns, test organization, and coverage enforcement for reliable codebases.
Comprehensive Rust coding guidelines with 179 rules across 14 categories. Use when writing, reviewing, or refactoring Rust code. Covers ownership, error handling, async patterns, API design, memory optimization, performance, testing, and common anti-patterns. Invoke with /rust-skills.
Visual regression testing using Playwright with toHaveScreenshot(), masking, thresholds, cross-browser testing, and VUDA integration for AI-powered visual analysis
Comprehensive guide to building and scaling a SaaS as a solopreneur with vibe coding. Based on 88 real-world sources from Reddit, X/Twitter, and industry blogs.
| name | pyqt-dialogs |
| description | PyQt/PySide6 dialogs - QFileDialog, QMessageBox, QInputDialog, QColorDialog, custom QDialog patterns |
| metadata | {"author":"OSS AI Skills","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, # Current index
False # Editable
)
if ok:
print(f"Selected: {item}")
# Get multiline text
text, ok = QInputDialog.getMultiLineText(
self,
"Input",
"Enter description:",
"Default\ntext"
)
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)
self.email_edit.setText(email)
# Usage
dialog = InputDialog(self)
dialog.set_values("John", "john@example.com")
if dialog.exec() == QDialog.DialogCode.Accepted:
values = dialog.get_values()
print(f"Name: {values['name']}, Email: {values['email']}")
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
self.accept()
def validate(self):
import re
# Validate email
email = self.email_edit.text()
if not email:
self.error_label.setText("Email is required")
return False
if not re.match(r"[^@]+@[^@]+\.[^@]+", email):
self.error_label.setText("Invalid email format")
return False
self.error_label.clear()
return True
def get_values(self):
return {
"age": self.age_spin.value(),
"email": self.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):
self.page_container_layout.deleteWidget(self.pages[0])
self.page_container_layout.addWidget(self.pages[self.current_page])
else:
self.current_page = max(0, min(len(self.pages)-1, self.current_page))