当前位置: 首页 > news >正文

qt qml实现电话簿 通讯录

 qml实现电话簿,基于github上开源代码修改而来,增加了搜索和展开,效果如下

代码如下

#include <QGuiApplication>
#include <QQmlApplicationEngine>int main(int argc, char *argv[])
{QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);QGuiApplication app(argc, argv);QQmlApplicationEngine engine;engine.load(QUrl(QStringLiteral("qrc:/main.qml")));if (engine.rootObjects().isEmpty())return -1;return app.exec();
}
import QtQuick 2.7
import QtQuick.Layouts 1.1
import QtQuick.Controls 2.1
import "./Pinyin.js" as PinyinUtilItem {width: 320height: 480property int expandedIndex: -1property string searchKeyword: ""// ✅ 固定联系人数据:姓名 + 电话统一管理property var contacts: [{"name": "皮皮",       "phone1": "029-8888-1111", "phone2": "138-1234-5678", "phone3": "029-6666-2222"},{"name": "日历",       "phone1": "029-8888-2222", "phone2": "139-8765-4321", "phone3": "029-6666-3333"},{"name": "父亲",       "phone1": "029-8888-3333", "phone2": "136-1122-3344", "phone3": "029-6666-4444"},{"name": "额额额",     "phone1": "029-8888-4444", "phone2": "135-5555-6666", "phone3": "029-6666-5555"},{"name": "高大上",     "phone1": "029-8888-5555", "phone2": "134-7777-8888", "phone3": "029-6666-6666"},{"name": "黑凤梨",     "phone1": "029-8888-6666", "phone2": "137-9999-0000", "phone3": "029-6666-7777"},{"name": "阿文",       "phone1": "029-8888-7777", "phone2": "133-1111-2222", "phone3": "029-6666-8888"},{"name": "阿南",       "phone1": "029-8888-8888", "phone2": "132-3333-4444", "phone3": "029-6666-9999"},{"name": "#特殊",      "phone1": "029-8888-9999", "phone2": "131-5555-6666", "phone3": "029-6666-0000"},{"name": "*特殊",      "phone1": "029-8888-0000", "phone2": "130-7777-8888", "phone3": "029-6666-1111"},{"name": "aaa",        "phone1": "029-8888-1111", "phone2": "138-1234-5678", "phone3": "029-6666-2222"},{"name": "AAA",        "phone1": "029-8888-2222", "phone2": "139-8765-4321", "phone3": "029-6666-3333"},{"name": "a啊a",       "phone1": "029-8888-3333", "phone2": "136-1122-3344", "phone3": "029-6666-4444"},{"name": "啊aa",       "phone1": "029-8888-4444", "phone2": "135-5555-6666", "phone3": "029-6666-5555"},{"name": "阿亮",       "phone1": "029-8888-5555", "phone2": "134-7777-8888", "phone3": "029-6666-6666"},{"name": "1阿1",       "phone1": "029-8888-6666", "phone2": "137-9999-0000", "phone3": "029-6666-7777"},{"name": "爸爸",       "phone1": "029-8888-7777", "phone2": "133-1111-2222", "phone3": "029-6666-8888"},{"name": "第八个",     "phone1": "029-8888-8888", "phone2": "132-3333-4444", "phone3": "029-6666-9999"},{"name": "奶奶",       "phone1": "029-8888-9999", "phone2": "131-5555-6666", "phone3": "029-6666-0000"},{"name": "叔叔",       "phone1": "029-8888-0000", "phone2": "130-7777-8888", "phone3": "029-6666-1111"},{"name": "智障啊",     "phone1": "029-8888-1111", "phone2": "138-1234-5678", "phone3": "029-6666-2222"},{"name": "满意",       "phone1": "029-8888-2222", "phone2": "139-8765-4321", "phone3": "029-6666-3333"},{"name": "岁月",       "phone1": "029-8888-3333", "phone2": "136-1122-3344", "phone3": "029-6666-4444"},{"name": "可能",       "phone1": "029-8888-4444", "phone2": "135-5555-6666", "phone3": "029-6666-5555"},{"name": "黄河",       "phone1": "029-8888-5555", "phone2": "134-7777-8888", "phone3": "029-6666-6666"}]Item {width: parent.widthheight: parent.heightanchors.centerIn: parentRectangle {anchors.fill: parentcolor: "#f0f0f0"}// 搜索框Item {width: parent.widthheight: 50anchors.top: parent.topRectangle {width: parent.width - 40height: 30anchors.centerIn: parentradius: 15color: "#ffffff"border.color: "#cccccc"border.width: 1Item {width: parent.widthheight: parent.heightImage {source: "qrc:/search.png"width: 15height: 15anchors.left: parent.leftanchors.leftMargin: 8anchors.verticalCenter: parent.verticalCenter}TextField {width: parent.width - 40height: parent.heightanchors.left: parent.leftanchors.leftMargin: 23anchors.right: parent.rightanchors.rightMargin: 8placeholderText: "搜索联系人..."font.pixelSize: 14color: "#333333"background: Item {}onTextChanged: {searchKeyword = textfilterContacts()}}}}}// 分组标题Component {id: sectionHeaderItem {width: 80height: 30Text {text: section.toUpperCase()font.pixelSize: 16anchors.left: parent.leftanchors.leftMargin: 8color: "#666666"anchors.bottom: parent.bottom}}}// 联系人列表ListView {id: listViewwidth: parent.widthheight: parent.height - 50anchors.bottom: parent.bottomclip: truemodel: searchKeyword.length > 0 ? filteredModel : testModeldelegate: Item {width: parent.widthheight: isExpanded ? 100 : 35readonly property int itemIndex: indexreadonly property bool isExpanded: listView.parent.parent.expandedIndex === itemIndexreadonly property string phone1: model.phone1readonly property string phone2: model.phone2readonly property string phone3: model.phone3// 展开时背景为白色Rectangle {anchors.fill: parentcolor: isExpanded ? "#ffffff" : "transparent"}// 联系人基本信息区域Item {width: parent.widthheight: 35Rectangle {width: parent.widthheight: 35color: "transparent"MouseArea {anchors.fill: parentacceptedButtons: Qt.LeftButtononClicked: {if (isExpanded) {listView.parent.parent.expandedIndex = -1} else {listView.parent.parent.expandedIndex = itemIndex}}}Text {text: listView.getShowTextSpecial(model.name)anchors.verticalCenter: parent.verticalCentercolor: "#333333"font.pixelSize: 16x: 24}}}// 电话信息区域(可展开)Item {y: 35width: parent.widthheight: isExpanded ? 65 : 0opacity: isExpanded ? 1 : 0Behavior on opacity { NumberAnimation { duration: 200 } }Behavior on height { NumberAnimation { duration: 200 } }// 三个电话号码(带标签)Text {text: "单位电话:" + phone1y: 0x: 48color: "#333333"font.pixelSize: 14}Text {text: "家庭座机:" + phone3y: 20x: 48color: "#333333"font.pixelSize: 14}Text {text: "手机:" + phone2y: 40x: 48color: "#333333"font.pixelSize: 14}}}ScrollIndicator.vertical: ScrollIndicator {anchors.right: parent.rightanchors.rightMargin: 8contentItem: Rectangle {implicitWidth: 3radius: implicitWidth / 2color: "#cccccc"}}function getShowTextSpecial(str) {var first = str[0]if (first === "#") return str.substr(1)return str}section.property: "pinyin"section.criteria: ViewSection.FirstCharactersection.delegate: sectionHeader}// 右侧字母栏Item {width: 30height: parent.height - 50anchors.top: parent.topanchors.topMargin: 50anchors.right: parent.rightanchors.rightMargin: 5MouseArea {anchors.fill: parentfunction changeBigText() {bigTip.visible = truevar index = parseInt(mouseY / 10)if (index < 0) index = 0if (index > 26) index = 26bigText.text = qsTr(letters[index] + "")var search_index = getIndexByLab(bigText.text)if (search_index >= 0)listView.positionViewAtIndex(search_index, ListView.Beginning)}function getIndexByLab(lab) {for (var i = 0; i < testModel.count; i++) {if (testModel.get(i).pinyin.substr(0, 1).toUpperCase() === lab) {return i}}return -1}onPositionChanged: changeBigText()onPressed: changeBigText()onReleased: bigTip.visible = false}Column {spacing: 0Repeater {model: lettersdelegate: Text {width: 30height: 14text: modelDatafont.pixelSize: 12color: "#666666"horizontalAlignment: Text.AlignHCenterverticalAlignment: Text.AlignVCenter}}}}// 大字母提示Rectangle {width: 30height: widthradius: width / 2color: "#ffffff"anchors.centerIn: parentvisible: falseid: bigTipText {id: bigTexttext: qsTr("A")font.pixelSize: 16color: "#333333"anchors.centerIn: parent}}}property var letters: ["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","#"]function generateData(contact) {var name = contact.namevar pinyin = PinyinUtil.pinyin.getFullChars(name)return {name: name,pinyin: pinyin,phone1: contact.phone1,phone2: contact.phone2,phone3: contact.phone3}}function chack_special(str) {var pattern1 = new RegExp("[`~!@#$^&*()=|{}':;',\\[\\].<>《》/?~!@#¥……&*()——|{}【】‘;:”“'。,、? ]")var pattern2 = /^[0-9]*$/return pattern1.test(str) || pattern2.test(str)}function moveFirstToEnd(array) {var first = array[0]array.push(first)array.shift()}ListModel {id: filteredModel}function filterContacts() {filteredModel.clear()if (searchKeyword.length === 0) returnfor(var i = 0; i < testModel.count; i++) {var item = testModel.get(i)if (item.name.toLowerCase().indexOf(searchKeyword.toLowerCase()) !== -1 ||item.pinyin.toLowerCase().indexOf(searchKeyword.toLowerCase()) !== -1) {filteredModel.append(generateData(item))}}}ListModel {id: testModelComponent.onCompleted: {var resultArray = []for (var i = 0; i < contacts.length; i++) {var contact = contacts[i]var pinyin = PinyinUtil.pinyin.getFullChars(contact.name)resultArray.push({name: contact.name,pinyin: pinyin,phone1: contact.phone1,phone2: contact.phone2,phone3: contact.phone3})}resultArray.sort(function(a, b) {return a.pinyin.localeCompare(b.pinyin)})var specialNumber = 0for (var i = 0; i < resultArray.length; i++) {if (chack_special(resultArray[i].name.substr(0, 1))) {resultArray[i].name = "#" + resultArray[i].namespecialNumber++}}for (i = 0; i < specialNumber; i++) moveFirstToEnd(resultArray)for (i = 0; i < resultArray.length; i++) {testModel.append(resultArray[i])}}}
}

源码地址,欢迎star

http://www.dtcms.com/a/317996.html

相关文章:

  • [FBCTF2019]RCEService
  • apache-tomcat-11.0.9安装及环境变量配置
  • 认识MCP
  • java中普通流stream与并行流parallelStream的比较分析
  • Javascript/ES6+/Typescript重点内容篇——手撕(待总结)
  • 如何定位一个高并发场景下API响应时间从200ms突增到2s的问题
  • 数据结构---二级指针(应用场景)、内核链表、栈(系统栈、实现方式)、队列(实现方式、应用)
  • SQL168 统计作答次数
  • 简单介绍cgroups以及在K8s中的应用
  • DM数据库的安全版本SYSDBA无法修改其他用户密码?
  • 2025年COR SCI2区,船载AUV协同调度优化+海上风电机组水下检测,深度解析+性能实测
  • GPT-oss开源:200万小时淬炼AI Agent专属商用引擎
  • Vi与Vim的主要区别总结
  • Linux systemd 服务管理与 Firewall 防火墙配置
  • 【论文分析】【Agent】SEW: Self-Evolving Agentic Workflows for Automated Code Generatio
  • 从零开始的云计算生活——第三十八天,避坑落井,Docker容器模块
  • 《RedisTemplate 核心操作全解析》
  • 家庭宽带中的服务器如何被外网访问?
  • 无法解析 CentOS 官方镜像源的域名
  • 977.有序数组的平方
  • 什么是回调地址
  • 8、项目管理
  • PI 思维升级 解密电容器的选择与布局策略,带您追求极致平坦的电源阻抗
  • 个人自然人可不可以申请注册商标!
  • 2025国赛数学建模C题详细思路模型代码获取,备战国赛算法解析——决策树
  • Python Day24 多线程编程:核心机制、同步方法与实践案例
  • Lesson 33 Out of the darkness
  • 开疆智能ModbusTCP转Profinet网关连接EPSON机器人配置案例
  • c# winform 调用 海康威视工业相机(又全又细又简洁)
  • 字典树trie