3. 实现按钮点击事件与信号槽
任务目标
在QML中创建一个自定义按钮组件,使用MouseArea捕获点击事件,并通过信号槽机制连接到JavaScript函数,实现点击按钮后界面文本状态的实时更新。
环境依赖
本案例基于Qt 5.15+或Qt 6.x,需要Qt Quick模块。在项目文件(.pro)中确保包含:
QT += quick qml
CONFIG += qmltypes
完整实现
创建main.qml,包含自定义按钮组件与状态显示文本。核心逻辑:按钮内部MouseArea捕获点击,通过onClicked信号调用JavaScript函数handleClick(),该函数修改ListView的count属性并更新文本显示。
import QtQuick 2.15
import QtQuick.Window 2.15
Window {
id: root
width: 400
height: 300
visible: true
title: "按钮点击事件与信号槽"
// 状态数据
property int clickCount: 0
// 自定义按钮组件(内联定义)
Component {
id: customButton
Rectangle {
width: 120
height: 40
radius: 5
color: mouseArea.pressed ? "#d32f2f" : "#2196f3"
border.color: "#1565c0"
border.width: 2
Text {
anchors.centerIn: parent
text: "点击我"
color: "white"
font.pixelSize: 16
font.bold: true
}
MouseArea {
id: mouseArea
anchors.fill: parent
onClicked: {
// 信号槽连接:调用JavaScript函数
root.handleClick()
}
}
}
}
// 界面布局
Column {
anchors.centerIn: parent
spacing: 20
// 使用自定义按钮
Loader {
sourceComponent: customButton
}
// 状态显示文本
Text {
id: statusText
text: "当前点击次数: " + root.clickCount
font.pixelSize: 18
color: "#333333"
horizontalAlignment: Text.AlignHCenter
width: 200
}
}
// JavaScript函数:更新状态
function handleClick() {
root.clickCount += 1
statusText.text = "当前点击次数: " + root.clickCount
console.log("按钮被点击,总次数: " + root.clickCount)
}
}
运行方式
- 将上述代码保存为
main.qml,放在Qt项目目录中。 - 创建
main.cpp(标准Qt Quick入口):
#include <QGuiApplication>
#include <QQmlApplicationEngine>
int main(int argc, char *argv[]) {
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
return app.exec();
}
- 在
.pro文件中添加main.cpp和main.qml到SOURCES与RESOURCES,或使用qml命令行直接运行:qml main.qml。
验证方法
- 功能验证:运行程序后,点击蓝色按钮,按钮颜色在按下时变为红色(视觉反馈),同时下方文本“当前点击次数”数字递增。
- 信号槽验证:在Qt Creator的控制台输出中,每次点击会打印
按钮被点击,总次数: N(N为递增数字),证明onClicked信号成功连接到handleClick()函数。 - 通过条件:连续点击10次,文本显示“当前点击次数: 10”,且控制台输出10条对应日志,即判定实现正确。
关键说明
- 本案例使用
Loader动态加载内联组件,也可直接使用Rectangle实例化按钮,效果相同。 - 信号槽连接采用QML语法:
MouseArea的onClicked信号直接绑定到父级Window的JavaScript函数handleClick(),这是QML中推荐的信号槽写法。 - 状态更新通过修改
root.clickCount属性并同步更新Text文本实现,避免直接操作DOM,符合QML响应式设计。