Fluent Design file picker widgets for PyQt6
Project description
fluent-filepicker
Fluent Design file picker widgets for PyQt6.
Drop-in widgets that let users select files via drag & drop or a native file dialog — styled after Microsoft's Fluent Design System, with full dark and light theme support.
Features
- Single-file and multi-file picker widgets
- Drag & drop with live valid / invalid visual feedback
- Native file-dialog integration (single and multi-select)
- Extension filtering with "Supported: .pdf, .png …" hint
- Compact flow-wrapped file chips with remove buttons
- Extension colour-coded badges (PDF → red, XLSX → green, …)
- Dark and light Fluent themes
- No external dependencies beyond PyQt6
Requirements
| Dependency | Version |
|---|---|
| Python | ≥ 3.9 |
| PyQt6 | ≥ 6.4.0 |
Installation
pip install fluent-filepicker
Quick start
Single-file picker
import sys
from PyQt6.QtWidgets import QApplication, QMainWindow, QWidget, QVBoxLayout
from fluent_filepicker import DropSingleFileWidget, Theme
app = QApplication(sys.argv)
window = QMainWindow()
container = QWidget()
layout = QVBoxLayout(container)
picker = DropSingleFileWidget(theme=Theme.DARK)
picker.set_allowed_extensions(["pdf", "docx", "png"])
picker.set_dialog_title("Choose a document")
picker.file_selected.connect(lambda path: print(f"Selected: {path}"))
picker.file_cleared.connect(lambda: print("Selection cleared"))
layout.addWidget(picker)
window.setCentralWidget(container)
window.resize(500, 300)
window.show()
sys.exit(app.exec())
Multi-file picker
import sys
from PyQt6.QtWidgets import QApplication, QMainWindow, QWidget, QVBoxLayout
from fluent_filepicker import DropMultiFilesWidget, Theme
app = QApplication(sys.argv)
window = QMainWindow()
container = QWidget()
layout = QVBoxLayout(container)
picker = DropMultiFilesWidget(theme=Theme.LIGHT)
picker.set_allowed_extensions(["jpg", "png", "webp"])
picker.set_max_file_count(10)
picker.set_dialog_title("Choose images")
picker.files_changed.connect(lambda paths: print(f"{len(paths)} file(s) selected"))
picker.file_added.connect(lambda path: print(f"Added: {path}"))
picker.file_removed.connect(lambda path: print(f"Removed: {path}"))
layout.addWidget(picker)
window.setCentralWidget(container)
window.resize(600, 400)
window.show()
sys.exit(app.exec())
API reference
Theme
from fluent_filepicker import Theme
Theme.DARK # dark Fluent theme (default)
Theme.LIGHT # light Fluent theme
DropSingleFileWidget
DropSingleFileWidget(
parent=None,
theme=Theme.DARK,
allowed_extensions=None, # e.g. ["pdf", "png"]
)
Signals
| Signal | Payload | Description |
|---|---|---|
file_selected |
str |
Emitted when a file is selected |
file_cleared |
— | Emitted when the selection is cleared |
Methods
| Method | Description |
|---|---|
set_theme(theme) |
Switch dark / light theme |
set_allowed_extensions(exts) |
Set accepted extensions (None = all) |
set_dialog_title(title) |
File-dialog window title |
set_dialog_directory(path) |
Default directory for the dialog |
set_hint_text(text) |
Text shown in the empty drop zone |
set_browse_text(text) |
Clickable "browse" text in the drop zone |
set_browse_button_text(text) |
Label of the button below the drop zone |
set_browse_button_visible(visible) |
Show / hide the browse button |
current_file() |
Return current path or None |
set_file(path) |
Programmatically set / clear the file |
clear_file() |
Clear selection and emit file_cleared |
has_file() |
True if a file is selected |
DropMultiFilesWidget
DropMultiFilesWidget(
parent=None,
theme=Theme.DARK,
allowed_extensions=None,
)
Signals
| Signal | Payload | Description |
|---|---|---|
files_changed |
list[str] |
Emitted on any change to the file list |
file_added |
str |
Emitted when a file is added |
file_removed |
str |
Emitted when a file is removed |
Methods
| Method | Description |
|---|---|
set_theme(theme) |
Switch dark / light theme |
set_allowed_extensions(exts) |
Set accepted extensions (None = all) |
set_max_file_count(n) |
Maximum number of files (None = unlimited) |
set_dialog_title(title) |
File-dialog window title |
set_dialog_directory(path) |
Default directory for the dialog |
set_hint_text(text) |
Text shown in the drop zone |
set_browse_text(text) |
Clickable "browse" text in the drop zone |
set_browse_button_text(text) |
Label of the "Add files" button |
set_browse_button_visible(visible) |
Show / hide the button |
current_files() |
Return list[str] of current paths |
set_files(paths) |
Replace the file list programmatically |
add_file(path) |
Add a single file; returns True if added |
remove_file(path) |
Remove a specific file |
clear_files() |
Remove all files |
file_count() |
Number of files currently selected |
has_files() |
True if at least one file is selected |
Theming
Both widgets adapt automatically when you call set_theme():
from fluent_filepicker import Theme
picker.set_theme(Theme.LIGHT)
picker.set_theme(Theme.DARK)
For system-level auto-switching you can connect to your own theme-change signal and propagate it:
system_theme_changed.connect(
lambda dark: picker.set_theme(Theme.DARK if dark else Theme.LIGHT)
)
Supported extension colours
Badges on file chips are colour-coded automatically:
| Category | Extensions | Colour |
|---|---|---|
| Red | ||
| Word | doc, docx | Blue |
| Excel | xls, xlsx | Green |
| PowerPoint | ppt, pptx | Orange |
| Images | png, jpg, jpeg, gif, webp | Teal |
| SVG | svg | Amber |
| Python | py | Steel blue |
| JavaScript | js | Yellow |
| TypeScript | ts | Blue |
| HTML | html | Orange-red |
| CSS | css | Blue |
| JSON | json | Dark amber |
| Plain text | txt | Grey |
| Archives | zip, rar, 7z | Purple |
| Video | mp4 | Blue |
| Audio | mp3, wav | Mint |
Unknown extensions receive a neutral grey badge.
License
MIT — see LICENSE for details.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file fluent_filepicker-0.1.0.tar.gz.
File metadata
- Download URL: fluent_filepicker-0.1.0.tar.gz
- Upload date:
- Size: 19.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f2babb3f23494ce90bb27ba7be86db32004f3e7584b26388ec569c2c921f8f70
|
|
| MD5 |
81da3a83ab07db490b03650268282d14
|
|
| BLAKE2b-256 |
80b4ecaf1f37ba6a1abb1e14e29f769ab74907c97d3886401ff25f04e92683b6
|
File details
Details for the file fluent_filepicker-0.1.0-py3-none-any.whl.
File metadata
- Download URL: fluent_filepicker-0.1.0-py3-none-any.whl
- Upload date:
- Size: 20.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c9085ba1ba367b62120931029d9971857e0cf54e5bb236efc6d4ef6bf82956ea
|
|
| MD5 |
7586792759eb79af872155cf4481524c
|
|
| BLAKE2b-256 |
16c831640e3568967c4ba34ce1f252e1f86f2be418881c2c1403d8ad7e0a66a3
|