主流编程大模型QML编程横向对比

今天晚上闲来无事,拉了一堆排行榜上的模型做了一个小测试,本次测试一共邀请了下面的这些模型进行同台竞技

Claude sonnet 4,Claude sonnet 4.5,Gemini2.5Pro,GPT5Codex,GPT5Mini,Qwen3Max,KimiK2

所有的都是一次提问,提示词都是使用QML创建一个计算器

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
Kimi2 生成了很多东西,但是Bug也一大堆,我手动修复了一下发现界面其实也还可以,不过没有鼠标悬浮的动效,但是也有键盘快捷键
在这里插入图片描述

额外内容

虽然 Claude Sonnet 4.5 看起来比 Claude Sonnet 4 美观性上差了一点,但是我点进代码之后发现实际上非常惊人,Sonnet 4 一共有 510 行,而 Sonnet 4.5 只有 181 行,Sonnet 4.5 在编程的时候真的会用到 QML 的特性让我非常震惊,他定义了一个自定义的组件CalcButton,以此大幅减少了代码量,而其他的模型,包括 Qwen3, Kimi K2, GLM 4.6, Sonnet 4都还是在用 Button,所以代码量飙升

总结

虽然 GLM 4.6 号称是对其了 Claude sonnet 4,但是在 QML 领域可能是缺乏训练数据,实际效果很明显比不上 Claude sonnet 4,除此之外大部分模型的功能都能正常实现,但是界面比较美观的只有 Claude 家的模型和 Kimi K2,不过 Kimi K2 功能有问题,没法运行。

期待未来国产模型越来越强,也期待年底的 GLM 5 能够达到或者超越 Sonnet 4

生成代码一览

Sonnet 4.5

import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15

ApplicationWindow {
    visible: true
    width: 320
    height: 480
    title: "计算器"
    
    property string displayText: "0"
    property real firstNumber: 0
    property string currentOperator: ""
    property bool startNewNumber: true
    
    Rectangle {
        anchors.fill: parent
        color: "#f0f0f0"
        
        ColumnLayout {
            anchors.fill: parent
            anchors.margins: 10
            spacing: 10
            
            // 显示屏
            Rectangle {
                Layout.fillWidth: true
                Layout.preferredHeight: 80
                color: "white"
                border.color: "#cccccc"
                border.width: 2
                radius: 5
                
                Text {
                    anchors.fill: parent
                    anchors.margins: 10
                    text: displayText
                    font.pixelSize: 32
                    horizontalAlignment: Text.AlignRight
                    verticalAlignment: Text.AlignVCenter
                    elide: Text.ElideLeft
                }
            }
            
            // 按钮网格
            GridLayout {
                Layout.fillWidth: true
                Layout.fillHeight: true
                columns: 4
                rowSpacing: 8
                columnSpacing: 8
                
                // 第一行:C, ÷, ×, -
                CalcButton { text: "C"; color: "#ff9999"; onClicked: clear() }
                CalcButton { text: "÷"; color: "#ffd699"; onClicked: operatorClicked("÷") }
                CalcButton { text: "×"; color: "#ffd699"; onClicked: operatorClicked("×") }
                CalcButton { text: "-"; color: "#ffd699"; onClicked: operatorClicked("-") }
                
                // 第二行:7, 8, 9, +
                CalcButton { text: "7"; onClicked: numberClicked("7") }
                CalcButton { text: "8"; onClicked: numberClicked("8") }
                CalcButton { text: "9"; onClicked: numberClicked("9") }
                CalcButton { text: "+"; color: "#ffd699"; Layout.rowSpan: 2; onClicked: operatorClicked("+") }
                
                // 第三行:4, 5, 6
                CalcButton { text: "4"; onClicked: numberClicked("4") }
                CalcButton { text: "5"; onClicked: numberClicked("5") }
                CalcButton { text: "6"; onClicked: numberClicked("6") }
                
                // 第四行:1, 2, 3, =
                CalcButton { text: "1"; onClicked: numberClicked("1") }
                CalcButton { text: "2"; onClicked: numberClicked("2") }
                CalcButton { text: "3"; onClicked: numberClicked("3") }
                CalcButton { text: "="; color: "#99ccff"; Layout.rowSpan: 2; onClicked: calculate() }
                
                // 第五行:0, .
                CalcButton { text: "0"; Layout.columnSpan: 2; onClicked: numberClicked("0") }
                CalcButton { text: "."; onClicked: numberClicked(".") }
            }
        }
    }
    
    // 数字按钮点击处理
    function numberClicked(num) {
        if (startNewNumber) {
            if (num === ".") {
                displayText = "0."
            } else {
                displayText = num
            }
            startNewNumber = false
        } else {
            if (num === "." && displayText.indexOf(".") !== -1) {
                return // 已有小数点,不再添加
            }
            displayText = displayText === "0" && num !== "." ? num : displayText + num
        }
    }
    
    // 运算符按钮点击处理
    function operatorClicked(op) {
        if (currentOperator !== "" && !startNewNumber) {
            calculate()
        }
        firstNumber = parseFloat(displayText)
        currentOperator = op
        startNewNumber = true
    }
    
    // 计算结果
    function calculate() {
        if (currentOperator === "") return
        
        var secondNumber = parseFloat(displayText)
        var result = 0
        
        switch (currentOperator) {
            case "+":
                result = firstNumber + secondNumber
                break
            case "-":
                result = firstNumber - secondNumber
                break
            case "×":
                result = firstNumber * secondNumber
                break
            case "÷":
                if (secondNumber === 0) {
                    displayText = "错误"
                    clear()
                    return
                }
                result = firstNumber / secondNumber
                break
        }
        
        // 格式化结果(去除不必要的小数位)
        displayText = result.toString()
        if (displayText.indexOf(".") !== -1) {
            var parts = displayText.split(".")
            if (parts[1].length > 8) {
                displayText = result.toFixed(8).replace(/\.?0+$/, "")
            }
        }
        
        currentOperator = ""
        startNewNumber = true
    }
    
    // 清除
    function clear() {
        displayText = "0"
        firstNumber = 0
        currentOperator = ""
        startNewNumber = true
    }
    
    // 自定义按钮组件
    component CalcButton: Button {
        property color color: "#e0e0e0"
        
        Layout.fillWidth: true
        Layout.fillHeight: true
        
        background: Rectangle {
            color: parent.pressed ? Qt.darker(parent.color, 1.2) : parent.color
            radius: 5
            border.color: "#999999"
            border.width: 1
        }
        
        contentItem: Text {
            text: parent.text
            font.pixelSize: 24
            font.bold: true
            horizontalAlignment: Text.AlignHCenter
            verticalAlignment: Text.AlignVCenter
            color: "#333333"
        }
    }
}

Sonnet 4

import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15

ApplicationWindow {
    id: window
    visible: true
    width: 320
    height: 500
    title: "计算器"
    
    property string currentNumber: "0"
    property string previousNumber: ""
    property string operator: ""
    property bool waitingForOperand: false
    
    Rectangle {
        anchors.fill: parent
        color: "#2b2b2b"
        
        Column {
            anchors.fill: parent
            anchors.margins: 10
            spacing: 10
            
            // 显示屏
            Rectangle {
                width: parent.width
                height: 80
                color: "#1a1a1a"
                border.color: "#404040"
                border.width: 1
                radius: 8
                
                Text {
                    id: display
                    anchors.right: parent.right
                    anchors.verticalCenter: parent.verticalCenter
                    anchors.rightMargin: 15
                    text: currentNumber
                    color: "white"
                    font.pixelSize: 28
                    font.bold: true
                }
            }
            
            // 按钮网格
            GridLayout {
                width: parent.width
                height: parent.height - 100
                columns: 4
                rowSpacing: 8
                columnSpacing: 8
                
                // 第一行:C, ±, %, ÷
                Button {
                    Layout.fillWidth: true
                    Layout.fillHeight: true
                    text: "C"
                    onClicked: clear()
                    background: Rectangle {
                        color: parent.pressed ? "#666666" : "#808080"
                        radius: 8
                    }
                    contentItem: Text {
                        text: parent.text
                        color: "black"
                        font.pixelSize: 20
                        font.bold: true
                        horizontalAlignment: Text.AlignHCenter
                        verticalAlignment: Text.AlignVCenter
                    }
                }
                
                Button {
                    Layout.fillWidth: true
                    Layout.fillHeight: true
                    text: "±"
                    onClicked: toggleSign()
                    background: Rectangle {
                        color: parent.pressed ? "#666666" : "#808080"
                        radius: 8
                    }
                    contentItem: Text {
                        text: parent.text
                        color: "black"
                        font.pixelSize: 20
                        font.bold: true
                        horizontalAlignment: Text.AlignHCenter
                        verticalAlignment: Text.AlignVCenter
                    }
                }
                
                Button {
                    Layout.fillWidth: true
                    Layout.fillHeight: true
                    text: "%"
                    onClicked: percentage()
                    background: Rectangle {
                        color: parent.pressed ? "#666666" : "#808080"
                        radius: 8
                    }
                    contentItem: Text {
                        text: parent.text
                        color: "black"
                        font.pixelSize: 20
                        font.bold: true
                        horizontalAlignment: Text.AlignHCenter
                        verticalAlignment: Text.AlignVCenter
                    }
                }
                
                Button {
                    Layout.fillWidth: true
                    Layout.fillHeight: true
                    text: "÷"
                    onClicked: setOperator("/")
                    background: Rectangle {
                        color: parent.pressed ? "#cc6600" : "#ff9500"
                        radius: 8
                    }
                    contentItem: Text {
                        text: parent.text
                        color: "white"
                        font.pixelSize: 24
                        font.bold: true
                        horizontalAlignment: Text.AlignHCenter
                        verticalAlignment: Text.AlignVCenter
                    }
                }
                
                // 第二行:7, 8, 9, ×
                Button {
                    Layout.fillWidth: true
                    Layout.fillHeight: true
                    text: "7"
                    onClicked: inputNumber("7")
                    background: Rectangle {
                        color: parent.pressed ? "#666666" : "#404040"
                        radius: 8
                    }
                    contentItem: Text {
                        text: parent.text
                        color: "white"
                        font.pixelSize: 24
                        font.bold: true
                        horizontalAlignment: Text.AlignHCenter
                        verticalAlignment: Text.AlignVCenter
                    }
                }
                
                Button {
                    Layout.fillWidth: true
                    Layout.fillHeight: true
                    text: "8"
                    onClicked: inputNumber("8")
                    background: Rectangle {
                        color: parent.pressed ? "#666666" : "#404040"
                        radius: 8
                    }
                    contentItem: Text {
                        text: parent.text
                        color: "white"
                        font.pixelSize: 24
                        font.bold: true
                        horizontalAlignment: Text.AlignHCenter
                        verticalAlignment: Text.AlignVCenter
                    }
                }
                
                Button {
                    Layout.fillWidth: true
                    Layout.fillHeight: true
                    text: "9"
                    onClicked: inputNumber("9")
                    background: Rectangle {
                        color: parent.pressed ? "#666666" : "#404040"
                        radius: 8
                    }
                    contentItem: Text {
                        text: parent.text
                        color: "white"
                        font.pixelSize: 24
                        font.bold: true
                        horizontalAlignment: Text.AlignHCenter
                        verticalAlignment: Text.AlignVCenter
                    }
                }
                
                Button {
                    Layout.fillWidth: true
                    Layout.fillHeight: true
                    text: "×"
                    onClicked: setOperator("*")
                    background: Rectangle {
                        color: parent.pressed ? "#cc6600" : "#ff9500"
                        radius: 8
                    }
                    contentItem: Text {
                        text: parent.text
                        color: "white"
                        font.pixelSize: 24
                        font.bold: true
                        horizontalAlignment: Text.AlignHCenter
                        verticalAlignment: Text.AlignVCenter
                    }
                }
                
                // 第三行:4, 5, 6, -
                Button {
                    Layout.fillWidth: true
                    Layout.fillHeight: true
                    text: "4"
                    onClicked: inputNumber("4")
                    background: Rectangle {
                        color: parent.pressed ? "#666666" : "#404040"
                        radius: 8
                    }
                    contentItem: Text {
                        text: parent.text
                        color: "white"
                        font.pixelSize: 24
                        font.bold: true
                        horizontalAlignment: Text.AlignHCenter
                        verticalAlignment: Text.AlignVCenter
                    }
                }
                
                Button {
                    Layout.fillWidth: true
                    Layout.fillHeight: true
                    text: "5"
                    onClicked: inputNumber("5")
                    background: Rectangle {
                        color: parent.pressed ? "#666666" : "#404040"
                        radius: 8
                    }
                    contentItem: Text {
                        text: parent.text
                        color: "white"
                        font.pixelSize: 24
                        font.bold: true
                        horizontalAlignment: Text.AlignHCenter
                        verticalAlignment: Text.AlignVCenter
                    }
                }
                
                Button {
                    Layout.fillWidth: true
                    Layout.fillHeight: true
                    text: "6"
                    onClicked: inputNumber("6")
                    background: Rectangle {
                        color: parent.pressed ? "#666666" : "#404040"
                        radius: 8
                    }
                    contentItem: Text {
                        text: parent.text
                        color: "white"
                        font.pixelSize: 24
                        font.bold: true
                        horizontalAlignment: Text.AlignHCenter
                        verticalAlignment: Text.AlignVCenter
                    }
                }
                
                Button {
                    Layout.fillWidth: true
                    Layout.fillHeight: true
                    text: "-"
                    onClicked: setOperator("-")
                    background: Rectangle {
                        color: parent.pressed ? "#cc6600" : "#ff9500"
                        radius: 8
                    }
                    contentItem: Text {
                        text: parent.text
                        color: "white"
                        font.pixelSize: 28
                        font.bold: true
                        horizontalAlignment: Text.AlignHCenter
                        verticalAlignment: Text.AlignVCenter
                    }
                }
                
                // 第四行:1, 2, 3, +
                Button {
                    Layout.fillWidth: true
                    Layout.fillHeight: true
                    text: "1"
                    onClicked: inputNumber("1")
                    background: Rectangle {
                        color: parent.pressed ? "#666666" : "#404040"
                        radius: 8
                    }
                    contentItem: Text {
                        text: parent.text
                        color: "white"
                        font.pixelSize: 24
                        font.bold: true
                        horizontalAlignment: Text.AlignHCenter
                        verticalAlignment: Text.AlignVCenter
                    }
                }
                
                Button {
                    Layout.fillWidth: true
                    Layout.fillHeight: true
                    text: "2"
                    onClicked: inputNumber("2")
                    background: Rectangle {
                        color: parent.pressed ? "#666666" : "#404040"
                        radius: 8
                    }
                    contentItem: Text {
                        text: parent.text
                        color: "white"
                        font.pixelSize: 24
                        font.bold: true
                        horizontalAlignment: Text.AlignHCenter
                        verticalAlignment: Text.AlignVCenter
                    }
                }
                
                Button {
                    Layout.fillWidth: true
                    Layout.fillHeight: true
                    text: "3"
                    onClicked: inputNumber("3")
                    background: Rectangle {
                        color: parent.pressed ? "#666666" : "#404040"
                        radius: 8
                    }
                    contentItem: Text {
                        text: parent.text
                        color: "white"
                        font.pixelSize: 24
                        font.bold: true
                        horizontalAlignment: Text.AlignHCenter
                        verticalAlignment: Text.AlignVCenter
                    }
                }
                
                Button {
                    Layout.fillWidth: true
                    Layout.fillHeight: true
                    text: "+"
                    onClicked: setOperator("+")
                    background: Rectangle {
                        color: parent.pressed ? "#cc6600" : "#ff9500"
                        radius: 8
                    }
                    contentItem: Text {
                        text: parent.text
                        color: "white"
                        font.pixelSize: 24
                        font.bold: true
                        horizontalAlignment: Text.AlignHCenter
                        verticalAlignment: Text.AlignVCenter
                    }
                }
                
                // 第五行:0 (占两列), ., =
                Button {
                    Layout.fillWidth: true
                    Layout.fillHeight: true
                    Layout.columnSpan: 2
                    text: "0"
                    onClicked: inputNumber("0")
                    background: Rectangle {
                        color: parent.pressed ? "#666666" : "#404040"
                        radius: 8
                    }
                    contentItem: Text {
                        text: parent.text
                        color: "white"
                        font.pixelSize: 24
                        font.bold: true
                        horizontalAlignment: Text.AlignHCenter
                        verticalAlignment: Text.AlignVCenter
                    }
                }
                
                Button {
                    Layout.fillWidth: true
                    Layout.fillHeight: true
                    text: "."
                    onClicked: inputDecimal()
                    background: Rectangle {
                        color: parent.pressed ? "#666666" : "#404040"
                        radius: 8
                    }
                    contentItem: Text {
                        text: parent.text
                        color: "white"
                        font.pixelSize: 24
                        font.bold: true
                        horizontalAlignment: Text.AlignHCenter
                        verticalAlignment: Text.AlignVCenter
                    }
                }
                
                Button {
                    Layout.fillWidth: true
                    Layout.fillHeight: true
                    text: "="
                    onClicked: calculate()
                    background: Rectangle {
                        color: parent.pressed ? "#cc6600" : "#ff9500"
                        radius: 8
                    }
                    contentItem: Text {
                        text: parent.text
                        color: "white"
                        font.pixelSize: 24
                        font.bold: true
                        horizontalAlignment: Text.AlignHCenter
                        verticalAlignment: Text.AlignVCenter
                    }
                }
            }
        }
    }
    
    // 计算器功能函数
    function inputNumber(num) {
        if (waitingForOperand) {
            currentNumber = num
            waitingForOperand = false
        } else {
            currentNumber = currentNumber === "0" ? num : currentNumber + num
        }
    }
    
    function inputDecimal() {
        if (waitingForOperand) {
            currentNumber = "0."
            waitingForOperand = false
        } else if (currentNumber.indexOf(".") === -1) {
            currentNumber += "."
        }
    }
    
    function clear() {
        currentNumber = "0"
        previousNumber = ""
        operator = ""
        waitingForOperand = false
    }
    
    function toggleSign() {
        if (currentNumber !== "0") {
            currentNumber = currentNumber.charAt(0) === "-" ? 
                           currentNumber.slice(1) : 
                           "-" + currentNumber
        }
    }
    
    function percentage() {
        currentNumber = (parseFloat(currentNumber) / 100).toString()
    }
    
    function setOperator(nextOperator) {
        var inputValue = parseFloat(currentNumber)
        
        if (previousNumber === "") {
            previousNumber = currentNumber
        } else if (operator !== "") {
            var prevValue = parseFloat(previousNumber)
            var result = performCalculation(prevValue, inputValue, operator)
            
            currentNumber = result.toString()
            previousNumber = currentNumber
        }
        
        waitingForOperand = true
        operator = nextOperator
    }
    
    function calculate() {
        var inputValue = parseFloat(currentNumber)
        
        if (previousNumber !== "" && operator !== "") {
            var prevValue = parseFloat(previousNumber)
            var result = performCalculation(prevValue, inputValue, operator)
            
            currentNumber = result.toString()
            previousNumber = ""
            operator = ""
            waitingForOperand = true
        }
    }
    
    function performCalculation(firstOperand, secondOperand, operator) {
        switch (operator) {
            case "+":
                return firstOperand + secondOperand
            case "-":
                return firstOperand - secondOperand
            case "*":
                return firstOperand * secondOperand
            case "/":
                if (secondOperand === 0) {
                    return "错误"
                }
                return firstOperand / secondOperand
            default:
                return secondOperand
        }
    }
}

Gemini 2.5 Pro

import QtQuick
import QtQuick.Controls
import QtQuick.Layouts

Window {
    id: root
    width: 320
    height: 480
    visible: true
    title: qsTr("Calculator")
    color: "#f0f0f0"

    // Function to perform calculation
    function calculate() {
        try {
            // A simple validation to prevent unsafe eval, not exhaustive
            if (/^[0-9+\-*/.() ]+$/.test(display.text)) {
                var result = eval(display.text);
                display.text = String(result);
            } else {
                display.text = "Error";
            }
        } catch (e) {
            display.text = "Error";
        }
    }

    ColumnLayout {
        anchors.fill: parent
        anchors.margins: 10
        spacing: 5

        // Display
        Text {
            id: display
            Layout.fillWidth: true
            Layout.preferredHeight: 80
            text: "0"
            font.pixelSize: 48
            horizontalAlignment: Text.AlignRight
            verticalAlignment: Text.AlignVCenter
            background: Rectangle {
                color: "white"
                border.color: "gray"
                radius: 5
            }
            clip: true
        }

        // Buttons
        GridLayout {
            Layout.fillWidth: true
            Layout.fillHeight: true
            columns: 4

            readonly property var buttons: [
                "C", "(", ")", "/",
                "7", "8", "9", "*",
                "4", "5", "6", "-",
                "1", "2", "3", "+",
                "0", ".", "=", ""
            ]

            Repeater {
                model: parent.buttons
                delegate: Button {
                    text: modelData
                    font.pixelSize: 24
                    Layout.fillWidth: true
                    Layout.fillHeight: true
                    visible: text !== ""

                    background: Rectangle {
                        color: parent.down ? "#d0d0d0" : "#e0e0e0"
                        border.color: "gray"
                        radius: 5
                    }

                    onClicked: {
                        if (text === "C") {
                            display.text = "0";
                        } else if (text === "=") {
                            calculate();
                        } else {
                            if (display.text === "0" || display.text === "Error") {
                                display.text = text;
                            } else {
                                display.text += text;
                            }
                        }
                    }

                    // Special styling for operator buttons
                    Component.onCompleted: {
                        if ("/*-+".includes(text)) {
                            background.color = "#f0ad4e";
                        }
                        if (text === "=") {
                            background.color = "#5cb85c";
                        }
                        if (text === "C") {
                            background.color = "#d9534f";
                        }
                    }
                }
            }
        }
    }
}

GLM 4.6

import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15

ApplicationWindow {
    id: root
    visible: true
    width: 300
    height: 400
    title: qsTr("QML 计算器")

    // =================================================================
    // 1. 状态和逻辑 (之前在 CalculatorLogic.qml 中的内容)
    // =================================================================

    // --- 状态属性 ---
    // 显示在屏幕上的文本
    property string displayText: "0"
    // 存储前一个操作数
    property string previousValue: ""
    // 存储当前操作符 (+, -, *, /)
    property string currentOperator: ""
    // 标记是否正在等待输入新的操作数
    property bool waitingForOperand: false

    // --- 逻辑函数 ---

    // 处理数字按钮 (0-9)
    function digitPressed(digit) {
        if (waitingForOperand) {
            displayText = digit;
            waitingForOperand = false;
        } else {
            displayText = displayText === "0" ? digit : displayText + digit;
        }
    }

    // 处理操作符按钮 (+, -, *, /)
    function operatorPressed(op) {
        const currentValue = parseFloat(displayText);

        if (previousValue !== "" && currentOperator !== "" && !waitingForOperand) {
            // 如果已经有操作符和前一个值,先进行计算
            calculate();
        }

        previousValue = displayText;
        currentOperator = op;
        waitingForOperand = true;
    }

    // 处理等号按钮 (=)
    function equalsPressed() {
        if (currentOperator === "") return; // 没有操作符,不计算
        calculate();
        currentOperator = ""; // 计算后清除操作符
    }

    // 处理清除按钮 (C)
    function clearPressed() {
        displayText = "0";
        previousValue = "";
        currentOperator = "";
        waitingForOperand = false;
    }

    // 处理小数点按钮 (.)
    function pointPressed() {
        if (waitingForOperand) {
            displayText = "0.";
            waitingForOperand = false;
        } else if (displayText.indexOf('.') === -1) {
            displayText += ".";
        }
    }

    // 处理正负号切换 (+/-)
    function signPressed() {
        displayText = (parseFloat(displayText) * -1).toString();
    }

    // --- 内部计算函数 ---
    function calculate() {
        const prev = parseFloat(previousValue);
        const current = parseFloat(displayText);
        let result = 0;

        switch (currentOperator) {
            case '+':
                result = prev + current;
                break;
            case '-':
                result = prev - current;
                break;
            case '*':
                result = prev * current;
                break;
            case '/':
                if (current === 0) {
                    displayText = "Error";
                    waitingForOperand = true;
                    return;
                }
                result = prev / current;
                break;
        }

        // 处理浮点数精度问题,并转换为字符串
        displayText = Number.isInteger(result) ? result.toString() : result.toFixed(8).replace(/\.?0+$/, "");
        waitingForOperand = true;
    }


    // =================================================================
    // 2. 用户界面 (之前在 main.qml 中的内容)
    // =================================================================

    // 使用垂直布局来组织显示屏和按钮区域
    ColumnLayout {
        anchors.fill: parent
        anchors.margins: 10
        spacing: 10

        // 显示屏
        TextField {
            id: display
            Layout.fillWidth: true
            Layout.preferredHeight: 60
            // 直接绑定到根对象的 displayText 属性
            text: root.displayText
            horizontalAlignment: TextInput.AlignRight
            font.pixelSize: 30
            font.bold: true
            readOnly: true
            background: Rectangle {
                color: "#f0f0f0"
                border.color: "#d0d0d0"
            }
        }

        // 按钮区域,使用网格布局
        GridLayout {
            id: grid
            Layout.fillWidth: true
            Layout.fillHeight: true
            columns: 4
            rowSpacing: 10
            columnSpacing: 10

            // 第一行
            Button { text: "C"; Layout.columnSpan: 2; font.pixelSize: 22; onClicked: root.clearPressed(); background: Rectangle { color: "#ff9500"; border.color: "#e68500"; radius: 5; } }
            Button { text: "+/-"; font.pixelSize: 22; onClicked: root.signPressed(); background: Rectangle { color: "#f5f5f5"; border.color: "#b0b0b0"; radius: 5; } }
            Button { text: "/"; font.pixelSize: 22; onClicked: root.operatorPressed(text); background: Rectangle { color: "#ff9500"; border.color: "#e68500"; radius: 5; } }

            // 第二行
            Button { text: "7"; font.pixelSize: 22; onClicked: root.digitPressed(text); background: Rectangle { color: "#f5f5f5"; border.color: "#b0b0b0"; radius: 5; } }
            Button { text: "8"; font.pixelSize: 22; onClicked: root.digitPressed(text); background: Rectangle { color: "#f5f5f5"; border.color: "#b0b0b0"; radius: 5; } }
            Button { text: "9"; font.pixelSize: 22; onClicked: root.digitPressed(text); background: Rectangle { color: "#f5f5f5"; border.color: "#b0b0b0"; radius: 5; } }
            Button { text: "*"; font.pixelSize: 22; onClicked: root.operatorPressed(text); background: Rectangle { color: "#ff9500"; border.color: "#e68500"; radius: 5; } }

            // 第三行
            Button { text: "4"; font.pixelSize: 22; onClicked: root.digitPressed(text); background: Rectangle { color: "#f5f5f5"; border.color: "#b0b0b0"; radius: 5; } }
            Button { text: "5"; font.pixelSize: 22; onClicked: root.digitPressed(text); background: Rectangle { color: "#f5f5f5"; border.color: "#b0b0b0"; radius: 5; } }
            Button { text: "6"; font.pixelSize: 22; onClicked: root.digitPressed(text); background: Rectangle { color: "#f5f5f5"; border.color: "#b0b0b0"; radius: 5; } }
            Button { text: "-"; font.pixelSize: 22; onClicked: root.operatorPressed(text); background: Rectangle { color: "#ff9500"; border.color: "#e68500"; radius: 5; } }

            // 第四行
            Button { text: "1"; font.pixelSize: 22; onClicked: root.digitPressed(text); background: Rectangle { color: "#f5f5f5"; border.color: "#b0b0b0"; radius: 5; } }
            Button { text: "2"; font.pixelSize: 22; onClicked: root.digitPressed(text); background: Rectangle { color: "#f5f5f5"; border.color: "#b0b0b0"; radius: 5; } }
            Button { text: "3"; font.pixelSize: 22; onClicked: root.digitPressed(text); background: Rectangle { color: "#f5f5f5"; border.color: "#b0b0b0"; radius: 5; } }
            Button { text: "+"; font.pixelSize: 22; onClicked: root.operatorPressed(text); background: Rectangle { color: "#ff9500"; border.color: "#e68500"; radius: 5; } }

            // 第五行
            Button { text: "0"; Layout.columnSpan: 2; font.pixelSize: 22; onClicked: root.digitPressed(text); background: Rectangle { color: "#f5f5f5"; border.color: "#b0b0b0"; radius: 5; } }
            Button { text: "."; font.pixelSize: 22; onClicked: root.pointPressed(); background: Rectangle { color: "#f5f5f5"; border.color: "#b0b0b0"; radius: 5; } }
            Button { text: "="; font.pixelSize: 22; onClicked: root.equalsPressed(); background: Rectangle { color: "#ff9500"; border.color: "#e68500"; radius: 5; } }
        }
    }
}

GPT5 Codex

import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15

ApplicationWindow {
    width: 320
    height: 480
    visible: true
    title: qsTr("Calculator")

    property string displayText: "0"
    property double previousValue: 0
    property string pendingOperator: ""
    property bool resetDisplay: false

    function resetError() {
        if (displayText === "Error")
            displayText = "0"
    }

    function handleNumber(digit) {
        resetError()
        if (resetDisplay || displayText === "0") {
            displayText = digit
        } else {
            displayText += digit
        }
        resetDisplay = false
    }

    function handleDecimal() {
        resetError()
        if (resetDisplay) {
            displayText = "0."
            resetDisplay = false
            return
        }
        if (displayText.indexOf(".") === -1)
            displayText += "."
    }

    function handleToggleSign() {
        resetError()
        if (displayText === "0")
            return
        if (displayText.charAt(0) === "-")
            displayText = displayText.slice(1)
        else
            displayText = "-" + displayText
    }

    function handleBackspace() {
        resetError()
        if (resetDisplay) {
            displayText = "0"
            resetDisplay = false
            return
        }
        if (displayText.length <= 1 || (displayText.length === 2 && displayText.startsWith("-"))) {
            displayText = "0"
        } else {
            displayText = displayText.slice(0, -1)
        }
    }

    function applyOperator(op) {
        resetError()
        var current = parseFloat(displayText)
        if (pendingOperator !== "")
            executePending(current)
        else
            previousValue = current
        pendingOperator = op
        resetDisplay = true
    }

    function executePending(current) {
        switch (pendingOperator) {
        case "+":
            previousValue += current
            break
        case "-":
            previousValue -= current
            break
        case "×":
            previousValue *= current
            break
        case "÷":
            if (current === 0) {
                displayText = "Error"
                previousValue = 0
                pendingOperator = ""
                resetDisplay = true
                return
            }
            previousValue /= current
            break
        default:
            previousValue = current
        }
        displayText = String(previousValue)
    }

    function handleEquals() {
        if (pendingOperator === "" || displayText === "Error")
            return
        executePending(parseFloat(displayText))
        pendingOperator = ""
        resetDisplay = true
    }

    function handleClear() {
        displayText = "0"
        previousValue = 0
        pendingOperator = ""
        resetDisplay = false
    }

    ColumnLayout {
        anchors.fill: parent
        anchors.margins: 16
        spacing: 12

        Rectangle {
            Layout.fillWidth: true
            Layout.preferredHeight: 80
            color: "#202020"
            radius: 6
            Text {
                anchors.fill: parent
                anchors.margins: 12
                horizontalAlignment: Text.AlignRight
                verticalAlignment: Text.AlignVCenter
                font.pixelSize: 36
                color: "#ffffff"
                text: displayText
            }
        }

        ColumnLayout {
            Layout.fillWidth: true
            Layout.fillHeight: true
            spacing: 8

            RowLayout {
                Layout.fillWidth: true
                spacing: 8
                Button { text: "C"; Layout.fillWidth: true; onClicked: handleClear() }
                Button { text: "÷"; Layout.fillWidth: true; onClicked: applyOperator("÷") }
                Button { text: "×"; Layout.fillWidth: true; onClicked: applyOperator("×") }
                Button { text: "←"; Layout.fillWidth: true; onClicked: handleBackspace() }
            }

            RowLayout {
                Layout.fillWidth: true
                spacing: 8
                Button { text: "7"; Layout.fillWidth: true; onClicked: handleNumber("7") }
                Button { text: "8"; Layout.fillWidth: true; onClicked: handleNumber("8") }
                Button { text: "9"; Layout.fillWidth: true; onClicked: handleNumber("9") }
                Button { text: "-"; Layout.fillWidth: true; onClicked: applyOperator("-") }
            }

            RowLayout {
                Layout.fillWidth: true
                spacing: 8
                Button { text: "4"; Layout.fillWidth: true; onClicked: handleNumber("4") }
                Button { text: "5"; Layout.fillWidth: true; onClicked: handleNumber("5") }
                Button { text: "6"; Layout.fillWidth: true; onClicked: handleNumber("6") }
                Button { text: "+"; Layout.fillWidth: true; onClicked: applyOperator("+") }
            }

            RowLayout {
                Layout.fillWidth: true
                spacing: 8
                Button { text: "1"; Layout.fillWidth: true; onClicked: handleNumber("1") }
                Button { text: "2"; Layout.fillWidth: true; onClicked: handleNumber("2") }
                Button { text: "3"; Layout.fillWidth: true; onClicked: handleNumber("3") }
                Button { text: "="; Layout.fillWidth: true; onClicked: handleEquals() }
            }

            RowLayout {
                Layout.fillWidth: true
                spacing: 8
                Button { text: "+/-"; Layout.fillWidth: true; onClicked: handleToggleSign() }
                Button { text: "0"; Layout.fillWidth: true; onClicked: handleNumber("0") }
                Button { text: "."; Layout.fillWidth: true; onClicked: handleDecimal() }
                Button { text: "="; Layout.fillWidth: true; onClicked: handleEquals() }
            }
        }
    }
}

GPT5 mini

import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15

ApplicationWindow {
    id: win
    width: 360
    height: 520
    visible: true
    title: qsTr("计算器 GPT5Mini")

    property string expr: ""
    property string displayText: expr === "" ? "0" : expr

    ColumnLayout {
        anchors.fill: parent
        anchors.margins: 12
        spacing: 12

        Rectangle {
            id: displayBg
            Layout.fillWidth: true
            height: 100
            color: "#222"
            radius: 8

            Text {
                id: display
                anchors.right: parent.right
                anchors.rightMargin: 12
                anchors.verticalCenter: parent.verticalCenter
                text: win.displayText
                font.pixelSize: 32
                color: "#fff"
                horizontalAlignment: Text.AlignRight
                verticalAlignment: Text.AlignVCenter
                elide: Text.ElideLeft
            }
        }

        // 按钮区
        GridLayout {
            id: grid
            Layout.fillWidth: true
            Layout.fillHeight: true
            columns: 4
            rowSpacing: 8
            columnSpacing: 8

            // 按钮标签顺序
            property var keys: [
                { label: "C", value: "C" }, { label: "⌫", value: "⌫" }, { label: "/", value: "/" }, { label: "*", value: "*" },
                { label: "7", value: "7" }, { label: "8", value: "8" }, { label: "9", value: "9" }, { label: "-", value: "-" },
                { label: "4", value: "4" }, { label: "5", value: "5" }, { label: "6", value: "6" }, { label: "+", value: "+" },
                { label: "1", value: "1" }, { label: "2", value: "2" }, { label: "3", value: "3" }, { label: "=", value: "=" },
                { label: "0", value: "0", columnSpan: 2 }, { label: ".", value: "." }, { label: "=", value: "=" }
            ]

            Repeater {
                model: keys.length
                Button {
                    Layout.preferredHeight: 60
                    Layout.preferredWidth: ((grid.width - (grid.columnSpacing * (grid.columns - 1))) / grid.columns) * Layout.columnSpan

                    text: keys[index].label

                    // 处理 0 占两列的视觉效果
                    Layout.columnSpan: keys[index].columnSpan || 1

                    onClicked: {
                        var key = keys[index].value;
                        if (key === "C") {
                            win.clearAll();
                        } else if (key === "⌫") {
                            win.backspace();
                        } else if (key === "=") {
                            win.compute();
                        } else {
                            win.append(key);
                        }
                    }
                }
            }
        }
    }

    function isOperator(ch) {
        return ch === "+" || ch === "-" || ch === "*" || ch === "/";
    }

    function append(text) {
        // 数字或点或运算符处理
        if (text === ".") {
            // 防止在当前数字中重复小数点
            var lastOp = -1;
            for (var i = expr.length - 1; i >= 0; --i) {
                if (isOperator(expr[i])) { lastOp = i; break; }
            }
            var current = expr.slice(lastOp + 1);
            if (current.indexOf(".") !== -1) return;
            if (current === "") expr += "0";
            expr += ".";
        } else if (isOperator(text)) {
            if (expr === "") {
                // 允许以负号开始
                if (text === "-") expr = "-";
                return;
            }
            var last = expr[expr.length - 1];
            if (isOperator(last)) {
                // 连续运算符则替换(允许 - 作为负号)
                if (text === "-" && last !== "-") {
                    expr += "-";
                } else {
                    expr = expr.slice(0, -1) + text;
                }
            } else {
                expr += text;
            }
        } else { // 数字
            expr += text;
        }
        displayText = expr === "" ? "0" : expr;
    }

    function backspace() {
        if (expr.length > 0) {
            expr = expr.slice(0, -1);
            displayText = expr === "" ? "0" : expr;
        }
    }

    function clearAll() {
        expr = "";
        displayText = "0";
    }

    function compute() {
        if (expr === "") return;
        // 避免末尾是运算符
        var last = expr[expr.length - 1];
        if (isOperator(last)) expr = expr.slice(0, -1);

        try {
            // 使用 Function 安全地计算表达式
            var result = Function('"use strict"; return (' + expr + ')')();
            if (result === Infinity || result === -Infinity || isNaN(result)) {
                displayText = "错误";
                expr = "";
                return;
            }
            // 格式化:去掉末尾多余的 0
            if (typeof result === "number") {
                // 保留最多 10 位小数,去掉尾部 0
                var fixed = parseFloat(result.toFixed(10)).toString();
                displayText = fixed;
                expr = fixed;
            } else {
                displayText = String(result);
                expr = displayText;
            }
        } catch (e) {
            displayText = "错误";
            expr = "";
        }
    }
}

Kimi K2

import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15

ApplicationWindow {
    id: root
    visible: true
    width: 320; height: 480
    minimumWidth: 280; minimumHeight: 420
    title: qsTr("QML 计算器")
    color: "#1e1e1e"

    property string expr: ""          // 当前表达式
    property bool justResult: false   // 刚算完结果,下次输入清空

    // 主布局
    ColumnLayout {
        anchors.fill: parent
        anchors.margins: 8
        spacing: 6

        // 显示屏
        Rectangle {
            Layout.fillWidth: true
            Layout.preferredHeight: root.height * 0.28
            color: "#2d2d30"
            radius: 10
            border.color: "#444"
            border.width: 1

            Text {
                id: display
                anchors {
                    right: parent.right; rightMargin: 12
                    verticalCenter: parent.verticalCenter
                }
                text: root.expr === "" ? "0" : root.expr
                font.pixelSize: Math.max(28, root.width / 8)
                color: "#f0f0f0"
            }
        }

        // 按钮区
        GridLayout {
            Layout.fillWidth: true
            Layout.fillHeight: true
            columns: 4
            rowSpacing: 6; columnSpacing: 6

            // 按钮数据:文字、角色、颜色
            readonly property var data: [
                // row 0
                {txt:"AC", role:"clear", bg:"#3c3c3c"},
                {txt:"+/-",role:"sign", bg:"#3c3c3c"},
                {txt:"%", role:"percent",bg:"#3c3c3c"},
                {txt:"÷", role:"op",    bg:"#ff9500"},
                // row 1
                {txt:"7", role:"num"},
                {txt:"8", role:"num"},
                {txt:"9", role:"num"},
                {txt:"×", role:"op",    bg:"#ff9500"},
                // row 2
                {txt:"4", role:"num"},
                {txt:"5", role:"num"},
                {txt:"6", role:"num"},
                {txt:"-", role:"op",    bg:"#ff9500"},
                // row 3
                {txt:"1", role:"num"},
                {txt:"2", role:"num"},
                {txt:"3", role:"num"},
                {txt:"+", role:"op",    bg:"#ff9500"},
                // row 4
                {txt:"0", role:"num", wide:true},
                {txt:".", role:"dot"},
                {txt:"=", role:"eq",    bg:"#ff9500"}
            ]

            Repeater {
                model: parent.data
                delegate: Rectangle {
                    color: modelData.bg || "#505050"
                    radius: 8
                    Layout.fillHeight: true
                    Layout.fillWidth: true
                    Layout.columnSpan: modelData.wide ? 2 : 1
                    border.width: 0.5
                    border.color: Qt.darker(color, 1.2)

                    Text {
                        anchors.centerIn: parent
                        text: modelData.txt
                        font { pixelSize: root.width / 12; bold: true }
                        color: "white"
                    }

                    MouseArea {
                        anchors.fill: parent
                        onClicked: handle(modelData)
                        onPressed: parent.scale = 0.92
                        onReleased: parent.scale = 1.0
                    }
                }
            }
        }
    }

    // 统一按键分发
    function handle(btn) {
        const r = btn.role, t = btn.txt
        if (r === "num")   append(t)
        else if (r === "op") appendOp(t)
        else if (r === "dot") appendDot()
        else if (r === "eq")  calculate()
        else if (r === "clear") { expr = ""; justResult = false }
        else if (r === "sign")  toggleSign()
        else if (r === "percent") percent()
    }

    function append(ch) {
        if (justResult) { expr = ""; justResult = false }
        expr += ch
    }

    function appendOp(op) {
        if (expr === "") return
        const last = expr.slice(-1)
        if ("+-×÷".indexOf(last) !== -1) expr = expr.slice(0, -1)
        expr += op
        justResult = false
    }

    function appendDot() {
        if (justResult) { expr = "0."; justResult = false; return }
        // 防止重复小数点
        const tokens = expr.split(/[\+\-\×÷]/)
        const cur = tokens[tokens.length - 1]
        if (cur.indexOf(".") === -1) expr += "."
    }

    function toggleSign() {
        if (expr === "") return
        const m = expr.match(/(.*)([\+\-\×÷])([^\+\-\×÷]*)$/)
        if (m) {
            const num = parseFloat(m[3])
            expr = m[1] + m[2] + (num * -1).toString()
        } else {
            expr = (parseFloat(expr) * -1).toString()
        }
    }

    function percent() {
        if (expr === "") return
        const last = parseFloat(expr.split(/[\+\-\×÷]/).pop())
        expr = expr.slice(0, -last.toString().length) + (last * 0.01).toString()
    }

    function calculate() {
        if (expr === "") return
        // 替换符号 → JS 可识别
        let js = expr.replace("×", "*").replace("÷", "/")
        try {
            const res = Number(eval(js).toFixed(8))  // 防浮点误差
            expr = res.toString()
            justResult = true
        } catch(e) {
            expr = "Error"
            justResult = true
        }
    }

    // 键盘支持
    Keys.onPressed: {
        const k = event.key
        if (k >= Qt.Key_0 && k <= Qt.Key_9) append((k - Qt.Key_0).toString())
        else if (k === Qt.Key_Plus)  appendOp("+")
        else if (k === Qt.Key_Minus) appendOp("-")
        else if (k === Qt.Key_Asterisk || k === Qt.Key_multiply) appendOp("×")
        else if (k === Qt.Key_Slash) appendOp("÷")
        else if (k === Qt.Key_Period || k === Qt.Key_Comma) appendDot()
        else if (k === Qt.Key_Return || k === Qt.Key_Equal) calculate()
        else if (k === Qt.Key_Escape) { expr = ""; justResult = false }
        else if (k === Qt.Key_Backspace) {
            if (!justResult && expr.length) expr = expr.slice(0, -1)
        }
    }
    focus: true
}

Qwen3 Max

import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15

ApplicationWindow {
    id: window
    visible: true
    width: 300
    height: 450
    title: "QML Calculator"

    property string currentInput: "0"
    property real lastNumber: 0
    property string operator: ""
    property bool waitingForOperand: false

    function clear() {
        currentInput = "0"
        lastNumber = 0
        operator = ""
        waitingForOperand = false
    }

    function inputDigit(digit) {
        if (waitingForOperand) {
            currentInput = "0"
            waitingForOperand = false
        }
        if (currentInput === "0") {
            currentInput = digit
        } else {
            currentInput += digit
        }
    }

    function inputOperator(op) {
        if (operator !== "") {
            calculate()
        } else {
            lastNumber = parseFloat(currentInput)
        }
        operator = op
        waitingForOperand = true
    }

    function calculate() {
        if (operator === "") return

        var current = parseFloat(currentInput)
        var result

        switch (operator) {
        case "+":
            result = lastNumber + current
            break
        case "-":
            result = lastNumber - current
            break
        case "*":
            result = lastNumber * current
            break
        case "/":
            if (current === 0) {
                currentInput = "Error"
                operator = ""
                waitingForOperand = true
                return
            }
            result = lastNumber / current
            break
        default:
            return
        }

        currentInput = (Math.round(result * 1e10) / 1e10).toString()
        operator = ""
        waitingForOperand = true
    }

    function backspace() {
        if (waitingForOperand || currentInput === "0" || currentInput === "Error") return
        currentInput = currentInput.slice(0, -1)
        if (currentInput === "" || currentInput === "-") {
            currentInput = "0"
        }
    }

    ColumnLayout {
        anchors.fill: parent
        anchors.margins: 10
        spacing: 10

        // 显示屏
        Rectangle {
            Layout.fillWidth: true
            height: 80
            radius: 10
            color: "#f0f0f0"
            border.color: "#ccc"
            border.width: 1

            Text {
                anchors.centerIn: parent
                text: currentInput
                font.pixelSize: 32
                horizontalAlignment: Text.AlignRight
                verticalAlignment: Text.AlignVCenter
                elide: Text.ElideRight
                width: parent.width - 20
            }
        }

        // 按钮网格
        GridLayout {
            Layout.fillWidth: true
            Layout.fillHeight: true
            rows: 5
            columns: 4
            columnSpacing: 8
            rowSpacing: 8

            // 第一行
            Button {
                text: "C"; font.pixelSize: 20
                onClicked: clear()
            }
            Button {
                text: "←"; font.pixelSize: 20
                onClicked: backspace()
            }
            Button {
                text: "÷"; font.pixelSize: 20
                onClicked: inputOperator("/")
            }
            Button {
                text: "×"; font.pixelSize: 20
                onClicked: inputOperator("*")
            }

            // 第二行
            Button {
                text: "7"; font.pixelSize: 20
                onClicked: inputDigit("7")
            }
            Button {
                text: "8"; font.pixelSize: 20
                onClicked: inputDigit("8")
            }
            Button {
                text: "9"; font.pixelSize: 20
                onClicked: inputDigit("9")
            }
            Button {
                text: "−"; font.pixelSize: 20
                onClicked: inputOperator("-")
            }

            // 第三行
            Button {
                text: "4"; font.pixelSize: 20
                onClicked: inputDigit("4")
            }
            Button {
                text: "5"; font.pixelSize: 20
                onClicked: inputDigit("5")
            }
            Button {
                text: "6"; font.pixelSize: 20
                onClicked: inputDigit("6")
            }
            Button {
                text: "+"; font.pixelSize: 20
                onClicked: inputOperator("+")
            }

            // 第四行
            Button {
                text: "1"; font.pixelSize: 20
                onClicked: inputDigit("1")
            }
            Button {
                text: "2"; font.pixelSize: 20
                onClicked: inputDigit("2")
            }
            Button {
                text: "3"; font.pixelSize: 20
                onClicked: inputDigit("3")
            }
            Button {
                Layout.rowSpan: 2
                text: "="; font.pixelSize: 20
                onClicked: calculate()
            }

            // 第五行
            Button {
                text: "0"; font.pixelSize: 20
                onClicked: inputDigit("0")
            }
            Button {
                text: "."; font.pixelSize: 20
                onClicked: {
                    if (waitingForOperand) {
                        currentInput = "0"
                        waitingForOperand = false
                    }
                    if (!currentInput.includes(".")) {
                        currentInput += "."
                    }
                }
            }
            // 空占位(因为 = 占两行,这里第5行第3列留空)
            Item { }
        }
    }
}

更多推荐