Skip to content
cccskills
FreePublished on GitHub

pyqt-core

Use when working with PyQt/PySide6 QtCore - signals, slots, properties, timers, settings, file I/O

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

See how to install

Files included (1)

  • SKILL.md10.5 KB

SKILL.md (original)

Review the instructions the agent will receive before you install.

PyQt Core - QtCore Module

QtCore provides core non-GUI functionality: signals/slots, timers, settings, and file I/O.

Overview

QtCore is the foundation of Qt. It provides:

  • Signal/Slot mechanism - Type-safe event handling
  • Properties - Bindable object properties
  • Timers - Periodic and single-shot timers
  • Settings - Persistent application configuration
  • File I/O - Cross-platform file operations

Signals and Slots

Signal Declaration (PySide6)

from PySide6.QtCore import QObject, Signal

class MyObject(QObject):
    # Define signals at class level
    valueChanged = Signal(int)
    nameChanged = Signal(str)
    dataReady = Signal(dict)
    errorOccurred = Signal(str)
    
    # Signal with multiple arguments
    positionChanged = Signal(int, int)
    
    # Signal with optional arguments
    progressChanged = Signal(int, arguments=['percent'])

Signal Declaration (PyQt6)

from PyQt6.QtCore import QObject, pyqtSignal

class MyObject(QObject):
    valueChanged = pyqtSignal(int)
    nameChanged = pyqtSignal(str)
    positionChanged = pyqtSignal(int, int)

Slot Declaration (PySide6)

from PySide6.QtCore import Slot

class MyObject(QObject):
    @Slot()
    def doSomething(self):
        print("Action performed")
    
    @Slot(int)
    def setValue(self, value):
        self._value = value
    
    @Slot(str, int)
    def processData(self, name, count):
        pass
    
    @Slot(result=str)  # Return type annotation
    def getName(self) -> str:
        return self._name

Slot Declaration (PyQt6)

from PyQt6.QtCore import pyqtSlot

class MyObject(QObject):
    @pyqtSlot()
    def doSomething(self):
        pass
    
    @pyqtSlot(int)
    def setValue(self, value):
        pass

Connecting Signals to Slots

# Connect signal to slot
button.clicked.connect(self.onButtonClick)
valueChanged.connect(self.updateValue)

# Connect with lambda
button.clicked.connect(lambda: print("Clicked!"))

# Connect with partial
from functools import partial
button.clicked.connect(partial(self.processItem, item_id))

# Disconnect
button.clicked.disconnect(self.onButtonClick)

# Check connection
is_connected = button.clicked.isConnected(self.onButtonClick)

# Emit signal
self.valueChanged.emit(42)
self.positionChanged.emit(x, y)

# Block signals temporarily
button.blockSignals(True)
button.setChecked(True)
button.blockSignals(False)

# Get signal emission count
count = button.receivers(button.clicked)

Connection Types

from PySide6.QtCore import Qt

# Auto (default) - Direct if same thread, Queued if different
button.clicked.connect(self.handleClick, Qt.AutoConnection)

# Direct - Slot called immediately in signal's thread
button.clicked.connect(self.handleClick, Qt.DirectConnection)

# Queued - Slot called when control returns to receiver's thread
worker.finished.connect(self.onFinished, Qt.QueuedConnection)

# BlockingQueued - Blocks until slot completes (use carefully!)
worker.result.connect(self.handleResult, Qt.BlockingQueuedConnection)

Properties

Property Declaration

from PySide6.QtCore import Property, Signal

class Person(QObject):
    nameChanged = Signal()
    
    def __init__(self):
        super().__init__()
        self._name = ""
    
    @Property(str, notify=nameChanged)
    def name(self):
        return self._name
    
    @name.setter
    def name(self, value):
        if self._name != value:
            self._name = value
            self.nameChanged.emit()

Using Properties

person = Person()
person.name = "Alice"  # Setter called
print(person.name)     # Getter called

# Connect to property change
person.nameChanged.connect(lambda: print("Name changed!"))

QTimer

Single-Shot Timer

from PySide6.QtCore import QTimer

# Call function after 1000ms
QTimer.singleShot(1000, self.onTimer)

# With lambda
QTimer.singleShot(500, lambda: print("Delayed!"))

# Cancel single-shot (store reference)
self.timer_id = QTimer.singleShot(1000, self.delayedAction)
# Note: Can't cancel singleShot, use regular timer instead

Periodic Timer

from PySide6.QtCore import QTimer

class MyWidget(QWidget):
    def __init__(self):
        super().__init__()
        
        # Create timer
        self.timer = QTimer(self)
        self.timer.timeout.connect(self.onTimeout)
        
        # Start with 100ms interval
        self.timer.start(100)
        
        # Or: self.timer.setInterval(100); self.timer.start()
    
    def onTimeout(self):
        print("Timer fired!")
    
    def stopTimer(self):
        self.timer.stop()
    
    def isRunning(self):
        return self.timer.isActive()
    
    def remainingTime(self):
        return self.timer.remainingTime()  # ms until next timeout

Timer Properties

timer = QTimer()

# Interval (milliseconds)
timer.setInterval(1000)  # 1 second
interval = timer.interval()

# Single-shot mode
timer.setSingleShot(True)  # Fires once then stops

# Timer type
timer.setTimerType(Qt.PreciseTimer)    # ~1ms accuracy
timer.setTimerType(Qt.CoarseTimer)     # ~5% accuracy (default)
timer.setTimerType(Qt.VeryCoarseTimer) # ~500ms accuracy

QSettings

Basic Usage

from PySide6.QtCore import QSettings

# Create settings (uses app name from QApplication)
settings = QSettings("MyCompany", "MyApp")

# Write values
settings.setValue("window/geometry", self.saveGeometry())
settings.setValue("window/state", self.saveState())
settings.setValue("editor/fontSize", 12)
settings.setValue("editor/fontFamily", "Monospace")

# Read values
geometry = settings.value("window/geometry")
font_size = settings.value("editor/fontSize", 10)  # Default 10
font_family = settings.value("editor/fontFamily", "Consolas")

# Check if key exists
if settings.contains("editor/theme"):
    theme = settings.value("editor/theme")

# Remove key
settings.remove("editor/temp")

# Clear all
settings.clear()

Settings Groups

settings = QSettings("MyCompany", "MyApp")

# Using beginGroup/endGroup
settings.beginGroup("editor")
settings.setValue("fontSize", 12)
settings.setValue("fontFamily", "Monospace")
settings.endGroup()

# Using array
settings.beginWriteArray("recentFiles")
for i, filepath in enumerate(recent_files):
    settings.setArrayIndex(i)
    settings.setValue("path", filepath)
settings.endArray()

# Read array
size = settings.beginReadArray("recentFiles")
for i in range(size):
    settings.setArrayIndex(i)
    path = settings.value("path")
settings.endArray()

Settings Format

from PySide6.QtCore import QSettings

# Native format (registry on Windows, plist on macOS, conf on Linux)
settings = QSettings("MyCompany", "MyApp")

# INI file format
settings = QSettings("config.ini", QSettings.IniFormat)

# Custom file location
settings = QSettings("/path/to/settings.conf", QSettings.IniFormat)

# Get file path
print(settings.fileName())

File I/O

QFile

from PySide6.QtCore import QFile, QIODevice

# Read file
file = QFile("data.txt")
if file.open(QIODevice.ReadOnly | QIODevice.Text):
    data = file.readAll()
    file.close()
    print(data)

# Write file
file = QFile("output.txt")
if file.open(QIODevice.WriteOnly | QIODevice.Text):
    file.write(b"Hello, World!")
    file.close()

# Append
file = QFile("log.txt")
if file.open(QIODevice.Append | QIODevice.Text):
    file.write(b"New log entry\n")
    file.close()

# Check exists
if QFile.exists("data.txt"):
    print("File exists")

# Remove file
QFile.remove("temp.txt")

# Copy file
QFile.copy("source.txt", "dest.txt")

# Rename file
QFile.rename("old.txt", "new.txt")

QTextStream

from PySide6.QtCore import QFile, QTextStream, QIODevice

# Read text
file = QFile("data.txt")
if file.open(QIODevice.ReadOnly | QIODevice.Text):
    stream = QTextStream(file)
    stream.setEncoding(QTextStream.Utf8)
    
    # Read all
    content = stream.readAll()
    
    # Read line by line
    while not stream.atEnd():
        line = stream.readLine()
        print(line)
    
    file.close()

# Write text
file = QFile("output.txt")
if file.open(QIODevice.WriteOnly | QIODevice.Text):
    stream = QTextStream(file)
    stream.setEncoding(QTextStream.Utf8)
    stream << "Line 1\n"
    stream << "Line 2\n"
    stream.writeString("Unicode: 你好")
    file.close()

QDir

from PySide6.QtCore import QDir

# Current directory
current = QDir.currentPath()
home = QDir.homePath()
temp = QDir.tempPath()

# Create directory
dir = QDir()
dir.mkpath("/path/to/new/directory")  # Creates all parent dirs

# Check if exists
if QDir("/path/to/dir").exists():
    print("Directory exists")

# List directory contents
dir = QDir("/path/to/dir")
entries = dir.entryList()  # Files and dirs
files = dir.entryList(QDir.Files)  # Only files
dirs = dir.entryList(QDir.Dirs | QDir.NoDotAndDotDot)  # Only subdirs

# With filters
entries = dir.entryList(["*.txt"], QDir.Files | QDir.Readable)

# Remove directory
QDir("/path/to/dir").rmdir(".")  # Must be empty

Best Practices

1. Use Type Hints

from PySide6.QtCore import Signal, Slot

class MyObject(QObject):
    valueChanged = Signal(int)
    
    @Slot(int)
    def setValue(self, value: int) -> None:
        self._value = value

2. Clean Up Timers

class MyWidget(QWidget):
    def __init__(self):
        super().__init__()
        self.timer = QTimer(self)  # Parent ensures cleanup
    
    def closeEvent(self, event):
        self.timer.stop()
        super().closeEvent(event)

3. Use Settings Defaults

# Always provide sensible defaults
font_size = settings.value("fontSize", 12, type=int)
theme = settings.value("theme", "dark")

4. Close Files

# Use context manager pattern
file = QFile("data.txt")
if file.open(QIODevice.ReadOnly):
    try:
        data = file.readAll()
    finally:
        file.close()

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