Dr. Cristián Maureira-Fredes
@cmaureir
Chilean Linux Meeting 2010
btw I use arch since 2009
Name | Language | Latest version | Last commit | License | Company |
---|---|---|---|---|---|
PySide | Python | 6.7.2 | - | LGPLv3/Commercial | The Qt Company |
PyQt | Python | 6.7.2 | - | GPLv3/Commercial | Riverbank Computing |
CXX-Qt | Rust | 6.x* | - | MIT/Apache 2.0 | KDAB |
qmetaobject-rs | Rust | 6.5.0 | 2024.08.07 | MIT | Woboq |
QtJambi | Java/Kotlin | 6.7.2 | 2024.06.25 | LGPLv2 | Omix Visualization |
QML-zig | Zig | 5.15.2 | 2024.08.11 | Apache 2.0 | - |
QML.jl | Julia | 6.5.2 | 2024.07.12 | MIT | JuliaGraphs |
RingQt | Ring | 5.15.15 | 2024.09.02 | MIT | - |
NodeGui | Node.js | 6.6.0 | 2024.05.31 | MIT | NodeGui |
nimqt | Nim | 6.4.3 | 2024.01.27 | GPL2 | - |
(updated on Sep 2nd, 2024)
Other 26 projects (some inactive) in wiki.qt.io/Language_Bindings
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QPushButton>
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
private slots:
void handleButton();
private:
QPushButton *m_button;
};
#endif // MAINWINDOW_H
#include "mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
m_button = new QPushButton("My Button", this);
connect(m_button, SIGNAL(clicked()), this,
SLOT(handleButton()));
}
void MainWindow::handleButton()
{
m_button->setText("Ready");
}
#include <QApplication>
#include "mainwindow.h"
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
MainWindow mainWindow;
mainWindow.show();
return app.exec(d);
}
// don't forget the CMakeLists.txt
import sys
from PySide6.QtCore import Slot
from PySide6.QtWidgets import (
QApplication, QMainWindow, QPushButton
)
class MainWindow(QMainWindow):
def __init__(self, parent=None):
QMainWindow.__init__(self, parent)
self.b = QPushButton("My Button", self)
self.b.clicked.connect(self.handle_button)
@Slot()
def handle_button(self):
self.b.setText("Ready")
if __name__ == "__main__":
app = QApplication(sys.argv)
mainWindow = MainWindow()
mainWindow.show()
sys.exit(app.exec())
scriptableapplication example
numpy.org The fundamental package for scientific computing with Python
>>> from PySide6.QtGui import QMatrix4x4
>>> import numpy as np
>>> m = np.eye(4)
>>> m.shape = 16
>>> m
array([[1., 0., 0., 0.],
[0., 1., 0., 0.],
[0., 0., 1., 0.],
[0., 0., 0., 1.]])
>>> QMatrix4x4(m)
PySide6.QtGui.QMatrix4x4((1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1))
// Also ad-hoc API
QPainter.drawPointsNp(PyArrayObject *x, PyArrayObject *y);
QXYSeries.appendNp(PyArrayObject *x, PyArrayObject *y);
QXYSeries.replaceNp(PyArrayObject *x, PyArrayObject *y);
snake_case
# Common Qt structure
# - Using setter/getter
table = QTableWidget()
table.setColumnCount(2)
button = QPushButton("Add")
button.setEnabled(False)
layout = QVBoxLayout()
layout.addWidget(table)
layout.addWidget(button)
from __feature__ import (
snake_case
)
table = QTableWidget()
table.set_column_count(2)
button = QPushButton("Add")
button.set_enabled(False)
layout = QVBoxLayout()
layout.add_widget(table)
layout.add_widget(button)
It might look strange to you, C++ developer.
# Common Qt structure
# - Using setter/getter
# - No writable properties
table = QTableWidget()
table.setColumnCount(2)
button = QPushButton("Add")
button.setEnabled(False)
layout = QVBoxLayout()
layout.addWidget(table)
layout.addWidget(button)
from __feature__ import (
snake_case, true_property
)
table = QTableWidget()
table.column_count = 2
button = QPushButton("Add")
button.enabled = False
layout = QVBoxLayout()
layout.add_widget(table)
layout.add_widget(button)
This was the #1 requested feature
QmlElement
from PySide6.QtQml import QmlElement
# ...
QML_IMPORT_NAME = "io.qt.some_name"
QML_IMPORT_MAJOR_VERSION = 1
@QmlElement
class Bridge(QObject):
@Slot(str, result=str)
def getColor(self, s):
# ...
// ...
import io.qt.some_name
// ...
Bridge {
id: bridge
}
Button {
id: red
text: "Red"
highlighted: true
Material.accent: Material.Red
onClicked: {
label.color = bridge.getColor(red.text)
}
}
// ...
# Wrappers
pyside6-assistant
pyside6-designer
pyside6-linguist
pyside6-lrelease
pyside6-lupdate
pyside6-qml
pyside6-qmlcachegen
pyside6-qmlimportscanner
pyside6-qmllint
pyside6-qmlsc
pyside6-qmltyperegistrar
pyside6-rcc
pyside6-uic
# Utilities
pyside6-genpyi
pyside6-metaobjectdump
# New tools
pyside6-project
pyside6-deploy
pyside6-android-deploy
QtAsyncio
# ...
import sys
import asyncio
import PySide6.QtAsyncio as QtAsyncio
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
widget = QWidget()
self.setCentralWidget(widget)
layout = QVBoxLayout(widget)
self.text = QLabel("The answer is 42.")
layout.addWidget(self.text, alignment=Qt.AlignmentFlag.AlignCenter)
async_trigger = QPushButton(text="What is the question?")
async_trigger.clicked.connect(lambda: asyncio.ensure_future(self.set_text()))
layout.addWidget(async_trigger, alignment=Qt.AlignmentFlag.AlignCenter)
async def set_text(self):
await asyncio.sleep(1)
self.text.setText("What do you get if you multiply six by nine?")
if __name__ == "__main__":
app = QApplication(sys.argv)
main_window = MainWindow()
main_window.show()
QtAsyncio.run(handle_sigint=True)
% tree Python
Python
├── autogen
│ └── settings.py
└── main.py
2 directories, 2 files
# Python/autogen/settings.py
url = "content/App.qml"
import_paths = [
".",
"imports",
"asset_imports",
]
# Python/main.py
# ...
from autogen.settings import url, import_paths
if __name__ == '__main__':
app = QGuiApplication(sys.argv)
engine = QQmlApplicationEngine()
app_dir = Path(__file__).parent.parent
engine.addImportPath(os.fspath(app_dir))
for path in import_paths:
engine.addImportPath(os.fspath(app_dir / path))
engine.load(os.fspath(app_dir/url))
if not engine.rootObjects():
sys.exit(-1)
sys.exit(app.exec())
⭐ To be announced this month.
static Demo demos[] = {
{"Main Window",
R"(# main_win is bound from C++
print("name=", main_win.objectName)
# point is bound from C++
print("point.x,y=", point.x(), point.y())
# Play with properties
main_win.objectName = "TestName"
print("changed name=", main_win.objectName)
# Create a point in Python
python_point = QPoint()
print("python_point.x,y=", python_point.x(),
python_point.y())
python_point.setX(500)
python_point.setY(500)
)"},
};
Merge request: Add Python bindings
import kimyou
from kimyou import Window, TextField, Button
def main(window: Window):
window.title = "Testing title"
window.layout_direction = "vertical"
name = TextField(value="Enter your name")
button = Button(text="Click me!",
on_click=lambda: print(f"Hello {name.value}"))
button2 = Button(text="Exit", on_click=window.exit)
# Vertical
#window.add(name)
#window.add(button)
#window.add(button2)
# Horizontal
window.add([name, button, button2])
kimyou.app(target=main)
Dr. Cristián Maureira-Fredes
@cmaureir
Slides:
qtinfo.dev/akademy2024
Cristián Maureira-Fredes | @cmaureir