Skip to content
cccskills
FreePublished on GitHub

pyqt-dialogs

Use when implementing PyQt/PySide6 dialogs - standard dialogs (QFileDialog, QMessageBox, QInputDialog, QColorDialog, QFontDialog), custom QDialog patterns, modal vs modeless dialogs, input validation, Qt 6 dialog APIs

The English summary is being prepared. Showing the original description.

See how to install

Files included (1)

  • SKILL.md12.4 KB

SKILL.md (original)

Review the instructions the agent will receive before you install.

PyQt Dialogs

Standard and custom dialog patterns for PyQt/PySide6 applications.

Standard Dialogs

QFileDialog

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)

QMessageBox

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())}")

QInputDialog

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"
)

QColorDialog

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)

QFontDialog

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
)

Custom Dialogs

Basic Custom Dialog

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']}")

Dialog with Validation

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()
        }

Modeless Dialog

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

Best Practices

  1. Use standard dialogs when possible - They're familiar and consistent
  2. Provide sensible defaults - Pre-fill common values
  3. Validate input before accepting - Show clear error messages
  4. Use QDialogButtonBox - Ensures correct button ordering per platform
  5. Set minimum size - Prevent dialogs from being too small
  6. Consider modeless dialogs - For search, find/replace, etc.

Qt 6 Dialogs

QDialog Modern Patterns

# ✅ 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 vs Non-modal

# 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

Best Practices Code Examples

# ✅ 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

Advanced Dialogs

Multi-page Dialog

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))

References

Reviews

No reviews yet. Tell others what you thought.

Comments

No login needed. Share how it worked for you, ask a question, or note where it did not run.

No comments yet. Be the first to write one.

Comments are published right away. Do not include personal information such as email addresses or phone numbers. Up to 2 URLs.

0 / 1,000 characters

This form is protected by reCAPTCHA, and the Google Privacy Policy and Terms of Service apply.

More skills from this repository

Use when building Python async HTTP services or clients with aiohttp - web server routing, middleware, WebSocket, SSE, streaming, client sessions, pytest-aiohttp testing, or troubleshooting SSL and timeout issues

The English summary is being prepared. Showing the original description.

CodeAtCode/oss-ai-skills24Updated Oct 9, 2026

Use when doing structural code search and rewriting - ast-grep linting, refactoring, multi-language patterns

The English summary is being prepared. Showing the original description.

CodeAtCode/oss-ai-skills24Updated Oct 9, 2026

Use when building GBA games with the BPCore Lua engine - entity, sprite and tilemap functions, SRAM save and load, link cable multiplayer protocol, camera and scrolling, or optimization patterns

The English summary is being prepared. Showing the original description.

CodeAtCode/oss-ai-skills24Updated Oct 9, 2026

celery

Free

Use when running background tasks with Celery - worker and broker configuration (Redis, RabbitMQ), task routing by name vs queue, chains/groups/chords, retry patterns (autoretry_for, retry_backoff), acks_late semantics, failure detection, and monitoring with Flower

The English summary is being prepared. Showing the original description.

CodeAtCode/oss-ai-skills24Updated Oct 9, 2026

django

Free

Use when building Django applications - security hardening, authentication and permissions, ORM optimization, PostgreSQL features, Django 6.0, migrations, testing, and ecosystem libraries

The English summary is being prepared. Showing the original description.

CodeAtCode/oss-ai-skills24Updated Oct 9, 2026

Use when customizing Django Admin - save_formset, get_search_results, formsets, queryset optimization, db_index, custom URLs

The English summary is being prepared. Showing the original description.

CodeAtCode/oss-ai-skills24Updated Oct 9, 2026

See all skills by CodeAtCode

Report a problem with this skill