| Generic | PySide6 | flet | tkinter | textual | wx |
|---|---|---|---|---|---|
| Application | QApplication | Page | Tk | App | App |
| Window | QMainWindow | ✓(Single) | Toplevel | ✓(Single) | Frame |
| HBox | QHBoxLayout | Row | Frame(grid) | Horizontal | BoxSizer |
| VBox | QVBoxLayout | Column | Frame(grid) | Vertical | BoxSizer |
| Grid | QGridLayout | - | GridBagSizer | ||
| Spacer | QSpacerItem | ✓ | ✓ | ✓ | ✓ |
| Divider | ✓ | StaticLine | |||
| Label | QLabel | Text | Label | Label/Button | StaticText |
| Button | QPushButton | ElevatedButton | Button | Button | Button |
| Checkbox | QCheckBox | Checkbox | Checkbutton | Checkbox | Checkbox |
| RadioButton | QRadioButton | Radio | Radiobutton | RadioButton | RadioButton |
| Canvas | ✓(QWidget) | Canvas | Canvas | ✓(Panel) | |
| TextField | QLineEdit | TextField | Entry | Input | TextCtrl |
| ProgressBar | QProgressBar | ProgressBar | Progressbar | ProgressBar | Gauge |
| Scroll | QScrollArea | ✓ | ✓ | ScrollableContainer | ScrolledPanel |
| Text | QLabel | Text | Label | Text | |
| Html | QLabel | ⚠ Text | ⚠ Label | ⚠ Text | |
| MarkDown | QLabel | Markdown | ⚠ Label | Markdown | |
| ComboBox | QComboBox | - | - | - | Combobox |
| Table | QTableView | - | - | - | |
| Tree | QTreeView | - | - | - | |
| Tabs | QTabWidget | Tabs | Notebook | Tabs | |
| Tab | ✓ | Tab | ✓ | ✓ | |
| MenuBar | QMenuBar | - | - | - | |
| Menu | QMenu | - | - | - | |
| MenuAction | QAction | - | - | - | |
| ToolBar | QToolBar | - | - | - | |
| ToolBarAction | QToolBarAction | - | - | - | |
| MdiArea | QMdiArea | - | - | - | |
| MdiSubWindow | QMdiSubWindow | - | - | - | |
| Splitter | QSplitter | - | - | - | |
| MatplotlibCanvas | FigureCanvas | ||||
| Modal | ✓ | - | - | - | |
| (Interop) | QtInPui | - | - | - | |
| (Interop) | PuiInQt | - | - | - |
| Generic | PySide6 | flet | tkinter | textual | wx |
|---|---|---|---|---|---|
| OpenDirectory | QFileDialog.getExistingDirectory | - | - | - | DirDialog |
| OpenFile | QFileDialog.getOpenFileName | - | - | - | FileDialog |
| OpenFiles | QFileDialog.getOpenFileNames | - | - | - | FileDialog |
| SaveFile | QFileDialog.getSaveFileName | - | - | - | FileDialog |
| Information | QMessageBox | - | - | - | MessageBox |
| Warning | QMessageBox | - | - | - | MessageBox |
| Critical | QMessageBox | - | - | - | MessageBox |
| Confirm | QMessageBox | - | - | - | MessageDialog |
| Prompt | QInputDialog | - | - | - | TextEntryDialog |
@PUIApp
def Example():
...is equivalent to
class Example(Application):
def content(self):
...@PUI
def SubView():
...is equivalent to
class SubView(PUIView):
def content(self):
...All callback interfaces accept an event object as the first argument. Other args/kwargs will be passed through to the callback function.
For example
def button_cb(event, data):
print(data)
Button("button").click(button_cb, 1)will invoke
button_cb(event, 1)
when the event is emitted.
- nothing for now
- .x, .y: double click position
- .x, .y: mouse down position
- .x, .y: mosue up position
- .x, .y: mouse move position
- .x, .y: wheel position
- .x_delta, .y_delta: pixel delta
- .h_delta, .v_delta: angle delta
Triggered when typing in TextField
- .value: text in edit buffer
Triggered when editing is finished in TextField
- .value: new value
- .layout(width=320, height=240, weight=1, padding=, margin=)
- .style(color=0xFF0000, bgColor=0x333333, fontSize=16, fontWeight="bold", fontFamily="Arial")
- .qt(HorizontalPolicy=, VerticalPolicy=, SizeConstraint=, StyleSheet={})
- .flet(k=v)
Top level element of an application
Application().qt(Style="fusion")flet and textual backends only support single window
Window([title=str][,size=(w,h)][,maximize=bool][,fullscreen=bool])Modal window
Modal(model[,offValue=None][,title=str][,size=(w,h)][,maximize=bool][,fullscreen=bool])Horizontal Linear Layout Container
HBox()Vertical Linear Layout Container
VBox()Grid Layout Container
with Grid():
Text("A").grid(row=0, column=0)
Text("B").grid(row=1, column=0, rowspan=2)Spacer inside linear layout containers
with HBox():
Text("Left")
Spacer()
Text("Right")Divider inside linear layout containers
with VBox():
Text("Top")
Divider()
Text("Bottom")Scrollable container
with Scroll().layout(weight=1).scrollY(Scroll.END):
with VBox():
for i in range(100):
Label(f"Row {i+1}")Single line clickable text with button appearance
Button(text).click(callback, *cb_args, **cb_kwargs)- .click
Single line clickable text
Label(text).click(callback, *cb_args, **cb_kwargs)- .click
Multiple line text viewer
Text(text)HTML viewer (only supported by PySide6 backend)
Html(html)Markdown viewer (not supported by tkinter backend)
Markdown(md)Editable Dropdown List Example
with ComboBox(editable=True, index_model=state("index"), text_model=state("text")):
ComboBoxItem("Item 1")
ComboBoxItem("Item 2")
ComboBoxItem("Item 3")
with ComboBox(editable=False, text_model=state("text")):
ComboBoxItem("Item 1", "Value 1")
ComboBoxItem("Item 2", "Value 2")
ComboBoxItem("Item 3", "Value 3")Single line text editor
TextField(binding, edit_buffer_binding=None)- .input: edit buffer changed
- .change: editing finished
Linear progress indicator
ProgressBar(progress `0-1`)Checkbox(label, model)- .click
RadioButton(label, value, model)def painter(canvas):
canvas.drawText(x, y, text, w=None, h=None, size=12, color=None, rotate=0, anchor=Anchor.LEFT_TOP)
canvas.drawLine(x1, y1, x2, y2, color=0xFF0000, width=1)
canvas.drawPolyline([x1, y2, ..., xn, yn], color=0xFF0000, width=1)
canvas.drawRect(x1, y1, x2, y2, fill=0xFF0000, stroke=0x00FF00, width=1)
canvas.drawShapely(shape, fill=0xFF0000, stroke=0x00FF00, width=1)
Canvas(painter)- .dblclick
- .mousedown
- .mouseup
- .mousemove
- .wheel
data = [(0,0), (1,3), (2,2)]
def plot(figure, data):
figure.clear()
sp = figure.add_subplot(111)
sp.axes.plot([d[0] for d in data], [d[1] for d in data])
MatplotlibCanvas(plot, data)Splitter(vertical=False)
with Splitter():
Label("Left")
Label("Right")Table widget
with Table():
with TableNode():
TableNode("A1")
TableNode("A2")
with TableNode():
TableNode("B1")
TableNode("B2")Table(adapter)Single column tree widget
There should be a TreeTable for multi/fixed-column trees and a NestedTable for variable-column trees, but they have not been implemented yet
with Tree():
with TreeNode("Root"):
with TreeNode("Sub 1"):
TreeNode("Sub 1-1")
TreeNode("Sub 1-2")
TreeNode("Sub 2")
with TreeNode("Sub 3"):
TreeNode("Sub 3-1")Tree(adapter)Wrapper for embedding native widget instance into PUI
Currently only supported by PySide6 backend
Wrapper for embedding PUI view into existing QT view hierarchy
Currently only supported by PySide6 backend