Dr. CristiΓ‘n Maureira-Fredes
@cmaureir
ALMA Common Software (ACS) Workshop, Chile 2009
Source TIOBE index October 2023
Most Popular technologies - Source StackOverflow Survey 2023
Admired and Desired Programming languages - Source StackOverflow Survey 2023
Most popular Frameworks - Source StackOverflow Survey 2023
Admired and Desired Frameworks - Source StackOverflow Survey 2023
Source Tauri Intro
Name | Language | Latest version | Last commit | License | Company |
---|---|---|---|---|---|
PySide | Python | 6.6.0 | - | LGPLv3/Commercial | The Qt Company |
PyQt | Python | 6.6.0 | - | GPLv3/Commercial | Riverbank Computing |
CXX-Qt | Rust | 6.x* | - | MIT/Apache 2.0 | KDAB |
qmetaobject-rs | Rust | 6.5.0 | 2023.11.03 | MIT | Woboq |
QtJambi | Java/Kotlin | 6.6.0 | 2023.10.17 | LGPLv2 | Omix Visualization |
QML-zig | Zig | 5.15 | 2023.08.17 | Apache 2.0 | - |
QML.jl | Julia | 6.5.2 | 2023.10.16 | MIT | JuliaGraphs |
RingQt | Ring | 5.15.15 | 2023.09.27 | MIT | - |
NodeGui | Node.js | 6.4.1 | 2023.08.28 | MIT | NodeGui |
nimqt | Nim | 6.4.3 | 2023.08.22 | GPL2 | - |
(updated on Nov 6th, 2023)
Other 26 projects (some inactive) in wiki.qt.io/Language_Bindings
Yesterday's talk
Volker & Maurice
(QtWS23)
#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);
}
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())
fn main() {
println!("Hello, world!");
}
$ rustc main.rs
$ ./main
Hello, world!
#include <iostream>
using namespace std;
int main() {
int nums[] = {1,2,3,4,5,6};
int five = nums[1] + nums[2];
cout << "Result: " << five";
}
fn main() {
let arr: [i32; 5] = [1, 2, 3, 4, 5];
let five = arr[1] + arr[2];
println!("Result: {}", five);
}
class Person {
public:
Person(string n, int a);
void talk();
string name;
int age;
};
Person::Person(string n, int a){
name = n;
age = a;
}
void Person::talk(){
cout << name << " says Hello!\n";
}
int main() {
Person maria("Maria", 22);
maria.talk();
}
// declare a struct
struct Person {
name: String,
age: i32
}
impl Person {
fn speak(&self){
println!("{} says Hello!",
self.name);
}
}
fn main() {
let maria = Person{
name: String::from("Maria"),
age: 5
};
maria.speak();
}
Not saying that we should re-write Qt...
#[cxx_qt::bridge]
pub mod qobject {
unsafe extern "C++" {
include!("cxx-qt-lib/qstring.h");
type QString = cxx_qt_lib::QString;
}
unsafe extern "RustQt" {
#[qobject]
#[qml_element]
#[qproperty(i32, number)]
#[qproperty(QString, string)]
type MyObject = super::MyObjectRust;
}
unsafe extern "RustQt" {
#[qinvokable]
fn increment_number(self: Pin<&mut MyObject>);
#[qinvokable]
fn say_hi(self: &MyObject,
string: &QString,
number: i32);
}
}
Snippet from: github.com/KDAB/cxx-qt/tree/main/examples/qml_minimal
cargo
)
$ cargo new yourapp
Created binary (application) `yourapp` package
$ tree yourapp
yourapp
βββ Cargo.toml
βββ src
βββ main.rs
2 directories, 2 files
~/yourapp $ cargo build
Compiling yourapp v0.1.0 (/home/cmaureir/yourapp)
Finished dev [unoptimized + debuginfo] target(s) in 0.68s
~/yourapp $ cargo run
Finished dev [unoptimized + debuginfo] target(s) in 0.02s
Running `target/debug/yourapp`
Hello, world!
Rust Features that I Want in C++ - David Sankel - CppNow 2022
comptime
)
// main.zig
const std = @import("std");
pub fn main() !void {
const stdout = std.io.getStdOut().writer();
try stdout.print("Hello, {s}!\n", .{"world"});
}
$ zig build-exe main.zig
$ ./hello
Hello, world!
#include <iostream>
using namespace std;
class Rectangle {
public:
float x;
float y;
Rectangle(float x, float y) :
x(x), y(y) {}
float area() {
return x * y;
}
};
int main(int argc, char *argv[]) {
Rectangle r = Rectangle(2.2, 3.3);
cout << "Rectangle area: "
<< r.area();
return 0;
}
const std = @import("std");
const Rectangle = struct {
x: f32,
y: f32,
pub fn init(x: f32, y: f32) Rectangle {
return Rectangle{
.x = x, .y = y,
};
}
pub fn area(self: Rectangle) f32 {
return self.x * self.y;
}
};
pub fn main() !void {
const r = Rectangle.init(2.2, 3.3);
const stdout = std.io.getStdOut().writer();
try stdout.print("Rectangle area: {}\n",
.{r.area()});
}
const c = @cImport({
// See github.com/ziglang/zig/issues/515
@cDefine("_NO_CRT_STDIO_INLINE", "1");
@cInclude("stdio.h");
});
pub fn main() void {
_ = c.printf("hello\n");
}
fn max(comptime T: type, a: T, b: T) T {
return if (a > b) a else b;
}
fn getBiggerFloat(a: f32, b: f32) f32 {
return max(f32, a, b);
}
fn getBiggerInt(a: u64, b: u64) u64 {
return max(u64, a, b);
}
// array literal
const m = [_]u8{ 'h', 'e', 'l', 'l', 'o' };
// get the size of an array
comptime {
assert(m.len == 5);
}
const std = @import("std");
const expect = std.testing.expect;
test {
const a = {};
const b = void{};
try expect(@TypeOf(a) == void);
try expect(@TypeOf(b) == void);
try expect(a == b);
}
$ zig init-exe
info: Created build.zig
info: Created src/main.zig
info: Next, try `zig build --help` or `zig build run`
$ tree
.
βββ build.zig
βββ src
βββ main.zig
2 directories, 2 files
$ zig build run
All your codebase are belong to us.
Run `zig build test` to run the tests.
$ tree zig-out
zig-out
βββ bin
βββ yourapp2
$ zig build-exe src/main.zig -target x86_64-windows-gnu
$ file main.exe
main.exe: PE32+ executable (console) x86-64, for MS Windows, 7 sections
$ zig build-exe src/main.zig -target aarch64-linux-musl
$ file main
main: ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV), statically linked, with debug_info, not stripped
Intro to the Zig Programming Language β’ Andrew Kelley β’ GOTO 2022
package hello api;
fn Main() -> i32 {
var s: auto = "Hello, world!";
Print(s);
return 0;
}
$ ./explorer hello.carbon
Hello, world!
// C++
#include <math.h>
#include <iostream>
#include <span>
#include <vector>
struct Circle {
float r;
}
void PrintTotalArea(std::span circles) {
float area = 0;
for (const Circle& c: circles) {
area += M_PI * c.r * c.r;
}
std::cout << "Total area: " << area << "\n";
}
auto main(int argc, char** argv) -> int {
std::vector circles = {{1.0}, {2.0}};
// Implicitly converts `vector` to `span`
PrintTotalArea(circles);
return 0;
}
// Carbon
package Geometry api;
import Math;
class Circle {
var r: f32;
}
fn PrintTotalArea(circles: Slice(Circle)) {
var area: f32 = 0;
for (c: Circle in circles) {
area += Math.Pi * c.r * c.r;
}
Print("Total area: {0}", area);
}
fn Main() -> i32 {
// A dynamically sized array, like `std::vector`.
var circles: Array(Circle) = ({.r = 1.0}, {.r = 2.0});
// Implicitly converts `Array` to `Slice`
PrintTotalArea(circles);
return 0;
}
Carbon Language Successor Strategy: From C++ Interop to Memory Safety - Chandler Carruth - CppNow 23
pick 5
(*) you all, and me
Be aware of other languages, no need to be an expert.
Keep in mind other languages when new API is being written down (or updated).
Try to add a general explanation of the method/class/module then a more language specific one.
Get inspired by what's out there. Innovation is not always necessary.
Spreading the knowledge should be priority 1, and making everything accesible priority 2.
Dr. CristiΓ‘n Maureira-Fredes
@cmaureir
QtWS23 CristiΓ‘n Maureira-Fredes | @cmaureir