├── .gitignore ├── Button ├── Button.qml ├── CheckBox.qml ├── RadioButton.qml ├── RoundRectangle.qml └── Switch.qml ├── Input ├── ComboBox.qml ├── RangeSlider.qml ├── SpinBox.qml ├── TextField.qml └── Tumbler.qml ├── LICENSE ├── Progress ├── ProgressBar.qml └── Slider.qml ├── QmlUI.qrc ├── QmlUI ├── .gitignore ├── QmlUI.pro ├── app.ico ├── main.cpp ├── main.qml └── snapshot │ └── demo.gif └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | # C++ objects and libs 2 | *.slo 3 | *.lo 4 | *.o 5 | *.a 6 | *.la 7 | *.lai 8 | *.so 9 | *.dll 10 | *.dylib 11 | 12 | # Qt-es 13 | object_script.*.Release 14 | object_script.*.Debug 15 | *_plugin_import.cpp 16 | /.qmake.cache 17 | /.qmake.stash 18 | *.pro.user 19 | *.pro.user.* 20 | *.qbs.user 21 | *.qbs.user.* 22 | *.moc 23 | moc_*.cpp 24 | moc_*.h 25 | qrc_*.cpp 26 | ui_*.h 27 | *.qmlc 28 | *.jsc 29 | Makefile* 30 | *build-* 31 | 32 | # Qt unit tests 33 | target_wrapper.* 34 | 35 | # QtCreator 36 | *.autosave 37 | 38 | # QtCreator Qml 39 | *.qmlproject.user 40 | *.qmlproject.user.* 41 | 42 | # QtCreator CMake 43 | CMakeLists.txt.user* 44 | -------------------------------------------------------------------------------- /Button/Button.qml: -------------------------------------------------------------------------------- 1 | /********************************************************** 2 | * Author: Qt君 3 | * 微信公众号: Qt君(首发) 4 | * Website: qtbig.com(后续更新) 5 | * Email: 2088201923@qq.com 6 | * QQ交流群: 732271126 7 | * LISCENSE: MIT 8 | ************************************************************/ 9 | import QtQuick 2.0 10 | import QtQuick.Controls 2.0 11 | import QtGraphicalEffects 1.0 12 | 13 | Button { 14 | id: root 15 | property color backgroundDefaultColor: "#4E5BF2" 16 | property color backgroundPressedColor: Qt.darker(backgroundDefaultColor, 1.2) 17 | property color contentItemTextColor: "white" 18 | 19 | text: "Button" 20 | hoverEnabled: true 21 | 22 | contentItem: Text { 23 | text: root.text 24 | color: root.contentItemTextColor 25 | font.pixelSize: 15 26 | font.family: "Arial" 27 | font.weight: Font.Thin 28 | horizontalAlignment: Text.AlignHCenter 29 | verticalAlignment: Text.AlignVCenter 30 | elide: Text.ElideRight 31 | } 32 | 33 | background: Rectangle { 34 | implicitWidth: 83 35 | implicitHeight: 37 36 | color: root.down ? root.backgroundPressedColor : root.backgroundDefaultColor 37 | 38 | Rectangle { 39 | anchors.fill: parent 40 | color: "#20000000" 41 | opacity: root.hovered 42 | Behavior on opacity { 43 | NumberAnimation { duration: 300 } 44 | } 45 | } 46 | 47 | radius: 3 48 | layer.enabled: true//root.hovered 49 | layer.effect: DropShadow { 50 | transparentBorder: true 51 | color: root.down ? root.backgroundPressedColor : root.backgroundDefaultColor 52 | samples: 20 /*20*/ 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /Button/CheckBox.qml: -------------------------------------------------------------------------------- 1 | /********************************************************** 2 | * Author: Qt君 3 | * 微信公众号: Qt君(首发) 4 | * Website: qtbig.com(后续更新) 5 | * Email: 2088201923@qq.com 6 | * QQ交流群: 732271126 7 | * LISCENSE: MIT 8 | ************************************************************/ 9 | import QtQuick 2.0 10 | import QtQuick.Controls 2.0 11 | 12 | CheckBox { 13 | id: root 14 | 15 | property color checkedColor: "#0ACF97" 16 | 17 | text: qsTr("CheckBox") 18 | 19 | hoverEnabled: true 20 | indicator: Rectangle { 21 | x: root.leftPadding 22 | anchors.verticalCenter: parent.verticalCenter 23 | width: 26; height: width 24 | antialiasing: true 25 | radius: 5 26 | border.width: 2 27 | border.color: root.checkedColor 28 | 29 | Rectangle { 30 | anchors.centerIn: parent 31 | width: parent.width*0.7; height: width 32 | antialiasing: true 33 | radius: parent.radius * 0.7 34 | color: { 35 | if (checked) 36 | return checkedColor 37 | 38 | if (hovered) 39 | return "#BDC3C7" 40 | 41 | return "#00000000" 42 | } 43 | visible: { 44 | if (checked) 45 | return true 46 | 47 | if (hovered) 48 | return true 49 | 50 | return false 51 | } 52 | opacity: visible 53 | 54 | Behavior on opacity { 55 | NumberAnimation { 56 | duration: 250 57 | } 58 | } 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /Button/RadioButton.qml: -------------------------------------------------------------------------------- 1 | /********************************************************** 2 | * Author: Qt君 3 | * 微信公众号: Qt君(首发) 4 | * Website: qtbig.com(后续更新) 5 | * Email: 2088201923@qq.com 6 | * QQ交流群: 732271126 7 | * LISCENSE: MIT 8 | ************************************************************/ 9 | import QtQuick 2.0 10 | import QtQuick.Controls 2.0 11 | 12 | RadioButton { 13 | id: root 14 | 15 | property color checkedColor: "#0ACF97" 16 | text: qsTr("RadioButton") 17 | 18 | hoverEnabled: true 19 | indicator: Rectangle { 20 | x: root.leftPadding 21 | anchors.verticalCenter: parent.verticalCenter 22 | width: 26; height: width 23 | antialiasing: true 24 | radius: width/2 25 | border.width: 2 26 | border.color: root.checkedColor 27 | 28 | Rectangle { 29 | anchors.centerIn: parent 30 | width: parent.width*0.7; height: width 31 | antialiasing: true 32 | radius: width/2 33 | color: { 34 | if (checked) 35 | return checkedColor 36 | 37 | if (hovered) 38 | return "#BDC3C7" 39 | 40 | return "#00000000" 41 | } 42 | visible: { 43 | if (checked) 44 | return true 45 | 46 | if (hovered) 47 | return true 48 | 49 | return false 50 | } 51 | opacity: visible 52 | 53 | Behavior on opacity { 54 | NumberAnimation { 55 | duration: 250 56 | } 57 | } 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /Button/RoundRectangle.qml: -------------------------------------------------------------------------------- 1 | /********************************************************** 2 | * Author: Qt君 3 | * 微信公众号: Qt君(首发) 4 | * Website: qtbig.com(后续更新) 5 | * Email: 2088201923@qq.com 6 | * QQ交流群: 732271126 7 | * LISCENSE: MIT 8 | ************************************************************/ 9 | import QtQuick 2.0 10 | 11 | Rectangle { 12 | id: root 13 | property int radiusCorners: Qt.AlignLeft | Qt.AlignRight | Qt.AlignTop | Qt.AlignBottom /* Default: */ 14 | /* 15 | Qt.AlignLeft | Qt.AlignLeft | Qt.AlignRight | Qt.AlignLeft | Qt.AlignLeft | 16 | Qt.AlignRight | Qt.AlignTop | Qt.AlignTop | Qt.AlignRight | Qt.AlignRight | 17 | None:0 Qt.AlignTop | Qt.AlignBottom Qt.AlignBottom Qt.AlignTop Qt.AlignBottom 18 | Qt.AlignBottom 19 | ***************** ************* *************** *************** ************* ***************** 20 | * * * * * * * * * * * * 21 | * * * * * * * * * * * * 22 | * * * * * * * * * * * * 23 | * * * * * * * * * * * * 24 | * * * * * * * * * * * * 25 | * * * * * * * * * * * * 26 | * * * * * * * * * * * * 27 | ***************** ************* *************** *************** ***************** ************* 28 | */ 29 | 30 | // width: 83; height: 37 31 | color: "#3498DB" 32 | radius: 8 33 | 34 | Repeater { 35 | model: [ { 36 | x: 0, 37 | y: 0, 38 | visible: internal.aligns(Qt.AlignLeft | Qt.AlignTop), 39 | radius: root.radius 40 | }, 41 | { 42 | x: root.width - root.radius, 43 | y: 0, 44 | visible: internal.aligns(Qt.AlignRight | Qt.AlignTop), 45 | radius: root.radius 46 | }, 47 | { 48 | x: 0, 49 | y: root.height - root.radius, 50 | visible: internal.aligns(Qt.AlignLeft | Qt.AlignBottom), 51 | radius: root.radius 52 | }, 53 | { 54 | x: root.width - root.radius, 55 | y: root.height - root.radius, 56 | visible: internal.aligns(Qt.AlignRight | Qt.AlignBottom), 57 | radius: root.radius 58 | } ] 59 | 60 | Rectangle { 61 | x: modelData.x; y: modelData.y 62 | width: modelData.radius; height: width 63 | visible: !modelData.visible 64 | color: parent.color 65 | } 66 | } 67 | 68 | QtObject { 69 | id: internal 70 | 71 | function aligns(direction) { 72 | return (root.radiusCorners & direction) === direction 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /Button/Switch.qml: -------------------------------------------------------------------------------- 1 | /********************************************************** 2 | * Author: Qt君 3 | * 微信公众号: Qt君(首发) 4 | * Website: qtbig.com(后续更新) 5 | * Email: 2088201923@qq.com 6 | * QQ交流群: 732271126 7 | * LISCENSE: MIT 8 | ************************************************************/ 9 | import QtQuick 2.0 10 | import QtQuick.Controls 2.0 11 | import QtGraphicalEffects 1.0 12 | 13 | Switch { 14 | id: root 15 | property color checkedColor: "#0ACF97" 16 | 17 | hoverEnabled: true 18 | indicator: Rectangle { 19 | width: 54 20 | height: 34 21 | radius: height / 2 22 | color: root.checked ? checkedColor : "white" 23 | border.width: 2 24 | border.color: root.checked ? checkedColor : "#E5E5E5" 25 | 26 | Rectangle { 27 | x: root.checked ? parent.width - width - 2 : 1 28 | width: root.checked ? parent.height - 4 : parent.height - 2 29 | height: width 30 | radius: width / 2 31 | anchors.verticalCenter: parent.verticalCenter 32 | color: "white" 33 | border.color: "#D5D5D5" 34 | 35 | Behavior on x { 36 | NumberAnimation { duration: 200 } 37 | } 38 | } 39 | 40 | layer.enabled: root.hovered 41 | layer.effect: DropShadow { 42 | id: dropShadow 43 | transparentBorder: true 44 | color: root.checked ? root.checkedColor : "#E5E5E5" 45 | samples: 10 /*20*/ 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /Input/ComboBox.qml: -------------------------------------------------------------------------------- 1 | /********************************************************** 2 | * Author: Qt君 3 | * 微信公众号: Qt君(首发) 4 | * Website: qtbig.com(后续更新) 5 | * Email: 2088201923@qq.com 6 | * QQ交流群: 732271126 7 | * LISCENSE: MIT 8 | ************************************************************/ 9 | import QtQuick 2.0 10 | import QtQuick.Controls 2.0 11 | import QtGraphicalEffects 1.0 12 | 13 | ComboBox { 14 | id: root 15 | 16 | property color checkedColor: "#1ABC9C" 17 | 18 | delegate: ItemDelegate { 19 | width: root.width 20 | 21 | contentItem: Text { 22 | text: modelData 23 | color: root.highlightedIndex === index ? "white" : "black" 24 | font.family: "Arial" 25 | elide: Text.ElideRight 26 | verticalAlignment: Text.AlignVCenter 27 | } 28 | 29 | background: Rectangle { 30 | width: parent.width 31 | height: parent.height 32 | color: root.highlightedIndex === index ? root.checkedColor : "#F3F4F5" 33 | } 34 | } 35 | 36 | indicator: Canvas { 37 | id: canvas 38 | x: root.width - width - 10 39 | y: (root.availableHeight - height) / 2 40 | width: 12 41 | height: 8 42 | contextType: "2d" 43 | 44 | Connections { 45 | target: root 46 | onPressedChanged: canvas.requestPaint() 47 | } 48 | 49 | onPaint: { 50 | context.reset(); 51 | context.moveTo(0, 0); 52 | context.lineTo(width, 0); 53 | context.lineTo(width / 2, height); 54 | context.closePath(); 55 | context.fillStyle = "white" 56 | context.fill(); 57 | } 58 | } 59 | 60 | contentItem: Item { 61 | width: root.background.width - root.indicator.width - 10 62 | height: root.background.height 63 | 64 | Text { 65 | anchors.verticalCenter: parent.verticalCenter 66 | x: 10 67 | text: root.displayText 68 | elide: Text.ElideRight 69 | 70 | font.pixelSize: 15 71 | font.family: "Arial" 72 | font.weight: Font.Thin 73 | color: root.down ? Qt.rgba(255, 255, 255, 0.75) : "white" 74 | } 75 | } 76 | 77 | background: Rectangle { 78 | implicitWidth: 102 79 | implicitHeight: 41 80 | color: root.down ? Qt.darker(root.checkedColor, 1.2) : root.checkedColor 81 | radius: 5 82 | 83 | layer.enabled: root.hovered | root.down 84 | layer.effect: DropShadow { 85 | transparentBorder: true 86 | color: root.checkedColor 87 | samples: 10 /*20*/ 88 | } 89 | } 90 | 91 | popup: Popup { 92 | y: root.height - 1 93 | width: root.width 94 | implicitHeight: contentItem.implicitHeight 95 | padding: 0 96 | 97 | contentItem: ListView { 98 | implicitHeight: contentHeight 99 | model: root.popup.visible ? root.delegateModel : null 100 | clip: true 101 | currentIndex: root.highlightedIndex 102 | 103 | ScrollIndicator.vertical: ScrollIndicator { } 104 | } 105 | 106 | background: Rectangle { 107 | color: "#F3F4F5" 108 | radius: 5 109 | clip: true 110 | 111 | layer.enabled: root.hovered | root.down 112 | layer.effect: DropShadow { 113 | transparentBorder: true 114 | color: "#F3F4F5" 115 | samples: 10 /*20*/ 116 | } 117 | } 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /Input/RangeSlider.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.5 2 | import QtQuick.Controls 2.0 3 | 4 | RangeSlider { 5 | id: root 6 | 7 | property color checkedColor: "#3498DB" 8 | 9 | first.value: 0.25 10 | second.value: 0.75 11 | 12 | background: Rectangle { 13 | x: root.leftPadding 14 | y: root.topPadding + root.availableHeight / 2 - height / 2 15 | implicitWidth: 200 16 | implicitHeight: 12 17 | width: root.availableWidth 18 | height: implicitHeight 19 | radius: height / 2 20 | color: "#EBEDEF" 21 | 22 | Rectangle { 23 | x: root.first.visualPosition * parent.width 24 | width: root.second.visualPosition * parent.width - x 25 | height: parent.height 26 | color: root.checkedColor 27 | radius: height / 2 28 | } 29 | } 30 | 31 | first.handle: Rectangle { 32 | x: root.leftPadding + first.visualPosition * (root.availableWidth - width) 33 | y: root.topPadding + root.availableHeight / 2 - height / 2 34 | implicitWidth: root.background.implicitHeight + 6 35 | implicitHeight: implicitWidth 36 | radius: implicitWidth / 2 37 | color: first.pressed ? Qt.darker(root.checkedColor, 1.2) : root.checkedColor 38 | border.color: Qt.darker(root.checkedColor, 0.93) 39 | } 40 | 41 | second.handle: Rectangle { 42 | x: root.leftPadding + second.visualPosition * (root.availableWidth - width) 43 | y: root.topPadding + root.availableHeight / 2 - height / 2 44 | implicitWidth: root.background.implicitHeight + 6 45 | implicitHeight: implicitWidth 46 | radius: implicitWidth / 2 47 | color: second.pressed ? Qt.darker(root.checkedColor, 1.2) : root.checkedColor 48 | border.color: Qt.darker(root.checkedColor, 0.93) 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /Input/SpinBox.qml: -------------------------------------------------------------------------------- 1 | /********************************************************** 2 | * Author: Qt君 3 | * 微信公众号: Qt君(首发) 4 | * Website: qtbig.com(后续更新) 5 | * Email: 2088201923@qq.com 6 | * QQ交流群: 732271126 7 | * LISCENSE: MIT 8 | ************************************************************/ 9 | import QtQuick 2.0 10 | import QtQuick.Controls 2.0 11 | import QtGraphicalEffects 1.0 12 | 13 | SpinBox { 14 | id: root 15 | 16 | property color color: "#3498DB" 17 | 18 | value: 50 19 | editable: true 20 | 21 | contentItem: TextInput { 22 | text: root.value 23 | 24 | font.pixelSize: 15 25 | font.family: "Arial" 26 | font.weight: Font.Thin 27 | 28 | horizontalAlignment: Qt.AlignHCenter 29 | verticalAlignment: Qt.AlignVCenter 30 | 31 | readOnly: !root.editable 32 | validator: root.validator 33 | } 34 | 35 | up.indicator: Rectangle { 36 | x: root.mirrored ? 0 : parent.width - width 37 | implicitWidth: 37 38 | implicitHeight: implicitWidth 39 | color: root.up.pressed ? "#EBEDEF" : root.color 40 | 41 | Text { 42 | text: "+" 43 | anchors.fill: parent 44 | color: root.up.pressed ? root.color : "white" 45 | 46 | font.bold: true 47 | font.pixelSize: root.font.pixelSize * 2 48 | fontSizeMode: Text.Fit 49 | 50 | horizontalAlignment: Text.AlignHCenter 51 | verticalAlignment: Text.AlignVCenter 52 | } 53 | } 54 | 55 | down.indicator: Rectangle { 56 | x: root.mirrored ? parent.width - width : 0 57 | implicitWidth: root.up.indicator.implicitWidth 58 | implicitHeight: implicitWidth 59 | color: root.down.pressed ? "#EBEDEF" : root.color 60 | 61 | Text { 62 | text: "-" 63 | anchors.fill: parent 64 | color: root.down.pressed ? root.color : "white" 65 | 66 | font.bold: true 67 | font.pixelSize: root.font.pixelSize * 2 68 | fontSizeMode: Text.Fit 69 | 70 | horizontalAlignment: Text.AlignHCenter 71 | verticalAlignment: Text.AlignVCenter 72 | } 73 | } 74 | 75 | background: Rectangle { 76 | implicitWidth: 138 77 | border.color: "#EBEDEF" 78 | 79 | layer.enabled: root.hovered 80 | layer.effect: DropShadow { 81 | id: dropShadow 82 | transparentBorder: true 83 | color: "#EEF2F7" 84 | samples: 8 /*20*/ 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /Input/TextField.qml: -------------------------------------------------------------------------------- 1 | /********************************************************** 2 | * Author: Qt君 3 | * 微信公众号: Qt君(首发) 4 | * Website: qtbig.com(后续更新) 5 | * Email: 2088201923@qq.com 6 | * QQ交流群: 732271126 7 | * LISCENSE: MIT 8 | ************************************************************/ 9 | import QtQuick 2.0 10 | import QtQuick.Controls 2.0 11 | import QtGraphicalEffects 1.0 12 | 13 | TextField { 14 | id: root 15 | 16 | property color checkedColor: "#D5DBDB" 17 | 18 | signal doubleClicked(var/*MouseEvent*/ event) 19 | 20 | placeholderText: qsTr("请输入内容") 21 | font.family: "Arial" 22 | font.pixelSize: 15 23 | font.weight: Font.Thin 24 | antialiasing: true 25 | 26 | background: Rectangle { 27 | implicitWidth: 213 28 | implicitHeight: 42 29 | radius: 8 30 | color: root.enabled ? "transparent" : "#F4F6F6" 31 | border.color: root.enabled ? root.checkedColor : "#D5DBDB" 32 | border.width: 2 33 | opacity: root.enabled ? 1 : 0.7 34 | 35 | layer.enabled: root.hovered 36 | layer.effect: DropShadow { 37 | id: dropShadow 38 | transparentBorder: true 39 | color: root.checkedColor 40 | samples: 10 /*20*/ 41 | } 42 | } 43 | 44 | cursorDelegate: Rectangle { 45 | width: 1 46 | height: parent.height * 0.4 47 | color: root.checkedColor 48 | visible: root.focus 49 | 50 | Timer { 51 | interval: 600 52 | repeat: true 53 | running: root.focus 54 | onRunningChanged: parent.visible = running 55 | onTriggered: parent.visible = !parent.visible 56 | } 57 | } 58 | 59 | onDoubleClicked: selectAll() 60 | 61 | /* note: This signal was introduced in QtQuick.Controls 2.1 (Qt 5.8). */ 62 | onPressed: { 63 | _private.mouseEvent = event 64 | _private.isCheckDoubleClickedEvent++ 65 | 66 | if (! _checkDoubleClickedEventTimer.running) 67 | _checkDoubleClickedEventTimer.restart() 68 | } 69 | 70 | /* Private */ 71 | Item { 72 | id: _private 73 | property int isCheckDoubleClickedEvent: 0 74 | property var/*MouseEvent*/ mouseEvent 75 | 76 | Timer { 77 | id: _checkDoubleClickedEventTimer 78 | running: false 79 | repeat: false 80 | interval: 180 81 | onTriggered: { 82 | if (_private.isCheckDoubleClickedEvent >= 2) { 83 | /* Double Clicked Event */ 84 | root.doubleClicked(_private.mouseEvent) 85 | } 86 | 87 | stop() 88 | _private.isCheckDoubleClickedEvent = 0 89 | } 90 | } 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /Input/Tumbler.qml: -------------------------------------------------------------------------------- 1 | /********************************************************** 2 | * Author: Qt君 3 | * 微信公众号: Qt君(首发) 4 | * Website: qtbig.com(后续更新) 5 | * Email: 2088201923@qq.com 6 | * QQ交流群: 732271126 7 | * LISCENSE: MIT 8 | ************************************************************/ 9 | import QtQuick 2.0 10 | import QtQuick.Controls 2.0 11 | import QtGraphicalEffects 1.0 12 | 13 | Tumbler { 14 | id: root 15 | 16 | property color currentItemColor: "#3498DB" 17 | 18 | visibleItemCount: 5 19 | 20 | delegate: Text { 21 | text: modelData 22 | color: root.currentItemColor 23 | 24 | font.family: "Arial" 25 | font.weight: Font.Thin 26 | font.pixelSize: 50 27 | 28 | horizontalAlignment: Text.AlignHCenter 29 | verticalAlignment: Text.AlignVCenter 30 | opacity: 1.0 - Math.abs(Tumbler.displacement) / root.visibleItemCount 31 | scale: opacity 32 | } 33 | 34 | /* 35 | contentItem: PathView { 36 | id: pathView 37 | model: root.model 38 | delegate: root.delegate 39 | clip: true 40 | pathItemCount: root.visibleItemCount 41 | currentIndex: root.currentIndex 42 | preferredHighlightBegin: 0.5 43 | preferredHighlightEnd: 0.5 44 | dragMargin: width / 2 45 | 46 | path: Path { 47 | startX: pathView.width / 2 48 | startY: 0 49 | PathLine { x: pathView.width/2; y: pathView.height } 50 | } 51 | } 52 | */ 53 | 54 | background: Rectangle { 55 | width: root.width; 56 | height: root.height 57 | border.color: "#EBEDEF" 58 | 59 | layer.enabled: root.hovered 60 | layer.effect: DropShadow { 61 | transparentBorder: true 62 | color: root.currentItemColor 63 | samples: 5 /*20*/ 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Qt君 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Progress/ProgressBar.qml: -------------------------------------------------------------------------------- 1 | /********************************************************** 2 | * Author: Qt君 3 | * 微信公众号: Qt君(首发) 4 | * Website: qtbig.com(后续更新) 5 | * Email: 2088201923@qq.com 6 | * QQ交流群: 732271126 7 | * LISCENSE: MIT 8 | ************************************************************/ 9 | import QtQuick 2.0 10 | import QtQuick.Controls 2.0 11 | 12 | ProgressBar { 13 | id: root 14 | 15 | property color color: "#3498DB" 16 | 17 | value: 0.5 18 | // padding: 2 19 | 20 | background: Rectangle { 21 | implicitWidth: 200 22 | implicitHeight: 20 23 | color: "#EBEDEF" 24 | // radius: implicitHeight / 2 25 | } 26 | 27 | contentItem: Item { 28 | implicitWidth: root.background.implicitWidth 29 | implicitHeight: root.background.implicitHeight 30 | 31 | Rectangle { 32 | width: root.visualPosition * parent.width 33 | height: parent.height 34 | color: root.color 35 | // radius: parent.height / 2 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Progress/Slider.qml: -------------------------------------------------------------------------------- 1 | /********************************************************** 2 | * Author: Qt君 3 | * 微信公众号: Qt君(首发) 4 | * Website: qtbig.com(后续更新) 5 | * Email: 2088201923@qq.com 6 | * QQ交流群: 732271126 7 | * LISCENSE: MIT 8 | ************************************************************/ 9 | import QtQuick 2.0 10 | import QtQuick.Controls 2.0 11 | import QtGraphicalEffects 1.0 12 | 13 | Slider { 14 | id: root 15 | 16 | property color checkedColor: "#3498DB" 17 | 18 | value: 0.5 19 | 20 | background: Rectangle { 21 | x: root.leftPadding 22 | y: root.topPadding + root.availableHeight / 2 - height / 2 23 | implicitWidth: 200 24 | implicitHeight: 12 25 | width: root.availableWidth 26 | height: implicitHeight 27 | radius: height / 2 28 | color: "#EBEDEF" 29 | 30 | Rectangle { 31 | width: root.visualPosition == 0 ? 0 : root.handle.x + root.handle.width / 2 32 | height: parent.height 33 | color: root.checkedColor 34 | radius: height / 2 35 | 36 | 37 | layer.enabled: root.hovered | root.pressed 38 | layer.effect: DropShadow { 39 | transparentBorder: true 40 | color: root.checkedColor 41 | samples: 8 42 | } 43 | } 44 | } 45 | 46 | handle: Rectangle { 47 | x: root.leftPadding + root.visualPosition * (root.availableWidth - width) 48 | y: root.topPadding + root.availableHeight / 2 - height / 2 49 | implicitWidth: root.background.implicitHeight + 6 50 | implicitHeight: implicitWidth 51 | radius: implicitWidth / 2 52 | color: root.pressed ? Qt.darker(root.checkedColor, 1.2) : root.checkedColor 53 | border.color: Qt.darker(root.checkedColor, 0.93) 54 | 55 | layer.enabled: root.hovered | root.pressed 56 | layer.effect: DropShadow { 57 | transparentBorder: true 58 | color: root.checkedColor 59 | samples: 10 /*20*/ 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /QmlUI.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | Button/Button.qml 4 | QmlUI/main.qml 5 | Button/RadioButton.qml 6 | Button/CheckBox.qml 7 | Button/Switch.qml 8 | Input/TextField.qml 9 | Input/ComboBox.qml 10 | Input/SpinBox.qml 11 | Progress/Slider.qml 12 | Progress/ProgressBar.qml 13 | Button/RoundRectangle.qml 14 | Input/Tumbler.qml 15 | Input/RangeSlider.qml 16 | 17 | 18 | -------------------------------------------------------------------------------- /QmlUI/.gitignore: -------------------------------------------------------------------------------- 1 | # This file is used to ignore files which are generated 2 | # ---------------------------------------------------------------------------- 3 | 4 | *~ 5 | *.autosave 6 | *.a 7 | *.core 8 | *.moc 9 | *.o 10 | *.obj 11 | *.orig 12 | *.rej 13 | *.so 14 | *.so.* 15 | *_pch.h.cpp 16 | *_resource.rc 17 | *.qm 18 | .#* 19 | *.*# 20 | core 21 | !core/ 22 | tags 23 | .DS_Store 24 | .directory 25 | *.debug 26 | Makefile* 27 | *.prl 28 | *.app 29 | moc_*.cpp 30 | ui_*.h 31 | qrc_*.cpp 32 | Thumbs.db 33 | *.res 34 | *.rc 35 | /.qmake.cache 36 | /.qmake.stash 37 | 38 | # qtcreator generated files 39 | *.pro.user* 40 | 41 | # xemacs temporary files 42 | *.flc 43 | 44 | # Vim temporary files 45 | .*.swp 46 | 47 | # Visual Studio generated files 48 | *.ib_pdb_index 49 | *.idb 50 | *.ilk 51 | *.pdb 52 | *.sln 53 | *.suo 54 | *.vcproj 55 | *vcproj.*.*.user 56 | *.ncb 57 | *.sdf 58 | *.opensdf 59 | *.vcxproj 60 | *vcxproj.* 61 | 62 | # MinGW generated files 63 | *.Debug 64 | *.Release 65 | 66 | # Python byte code 67 | *.pyc 68 | 69 | # Binaries 70 | # -------- 71 | *.dll 72 | *.exe 73 | 74 | -------------------------------------------------------------------------------- /QmlUI/QmlUI.pro: -------------------------------------------------------------------------------- 1 | QT += quick 2 | CONFIG += c++11 3 | 4 | # The following define makes your compiler emit warnings if you use 5 | # any Qt feature that has been marked deprecated (the exact warnings 6 | # depend on your compiler). Refer to the documentation for the 7 | # deprecated API to know how to port your code away from it. 8 | DEFINES += QT_DEPRECATED_WARNINGS 9 | 10 | # You can also make your code fail to compile if it uses deprecated APIs. 11 | # In order to do so, uncomment the following line. 12 | # You can also select to disable deprecated APIs only up to a certain version of Qt. 13 | #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 14 | 15 | SOURCES += \ 16 | main.cpp 17 | RC_ICONS = app.ico 18 | # Additional import path used to resolve QML modules in Qt Creator's code model 19 | QML_IMPORT_PATH = 20 | 21 | # Additional import path used to resolve QML modules just for Qt Quick Designer 22 | QML_DESIGNER_IMPORT_PATH = 23 | 24 | # Default rules for deployment. 25 | qnx: target.path = /tmp/$${TARGET}/bin 26 | else: unix:!android: target.path = /opt/$${TARGET}/bin 27 | !isEmpty(target.path): INSTALLS += target 28 | 29 | RESOURCES += \ 30 | ../QmlUI.qrc 31 | 32 | HEADERS += 33 | -------------------------------------------------------------------------------- /QmlUI/app.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aeagean/QmlUI/297d646dbe86db7f41163c136f214e92b8aac8fc/QmlUI/app.ico -------------------------------------------------------------------------------- /QmlUI/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(int argc, char *argv[]) 5 | { 6 | QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); 7 | 8 | QGuiApplication app(argc, argv); 9 | 10 | QQmlApplicationEngine engine; 11 | engine.load(QUrl("qrc:/QmlUI/main.qml")); 12 | if (engine.rootObjects().isEmpty()) 13 | return -1; 14 | 15 | return app.exec(); 16 | } 17 | -------------------------------------------------------------------------------- /QmlUI/main.qml: -------------------------------------------------------------------------------- 1 | /********************************************************** 2 | * Author: Qt君 3 | * 微信公众号: Qt君(首发) 4 | * Website: qtbig.com(后续更新) 5 | * Email: 2088201923@qq.com 6 | * QQ交流群: 732271126 7 | * LISCENSE: MIT 8 | ************************************************************/ 9 | import QtQuick 2.0 10 | import QtQuick.Window 2.2 11 | import QtQuick.Controls 2.0 12 | import QtQuick.Shapes 1.0 13 | import QtQuick.Layouts 1.0 14 | import "../Button" 15 | import "../Input" 16 | import "../Progress" 17 | 18 | Window { 19 | id: root 20 | visible: true 21 | width: 800 22 | height: 480 23 | title: qsTr("QmlUI by Qt君") 24 | 25 | ListView { 26 | anchors.fill: parent 27 | model: visualItem 28 | } 29 | 30 | VisualItemModel { 31 | id: visualItem 32 | 33 | Column { 34 | x: 10; y: 10 35 | spacing: 15 36 | 37 | Text { 38 | text: "Buttons: " 39 | font.pixelSize: 18 40 | font.family: "Arial" 41 | font.weight: Font.Thin 42 | color: "#a0000000" 43 | } 44 | 45 | GridLayout { 46 | width: root.width - 10 47 | rows: 8 48 | 49 | Button { 50 | text: "First" 51 | backgroundDefaultColor: "#727CF5" 52 | } 53 | 54 | Button { 55 | text: "Secondary" 56 | backgroundDefaultColor: "#5A6268" 57 | } 58 | 59 | Button { 60 | text: "Success" 61 | backgroundDefaultColor: "#0ACF97" 62 | } 63 | 64 | Button { 65 | text: "Danger" 66 | backgroundDefaultColor: "#F9375E" 67 | } 68 | 69 | Button { 70 | text: "Warning" 71 | contentItemTextColor: "#313A46" 72 | backgroundDefaultColor: "#FFBC00" 73 | } 74 | 75 | Button { 76 | text: "Info" 77 | backgroundDefaultColor: "#2B99B9" 78 | } 79 | 80 | Button { 81 | text: "Light" 82 | contentItemTextColor: "#313A46" 83 | backgroundDefaultColor: "#EEF2F7" 84 | } 85 | 86 | Button { 87 | backgroundDefaultColor: "#212730" 88 | backgroundPressedColor: "#313A46" 89 | } 90 | } 91 | 92 | Text { 93 | text: "Radio Button: " 94 | font.pixelSize: 18 95 | font.family: "Arial" 96 | font.weight: Font.Thin 97 | color: "#a0000000" 98 | } 99 | 100 | GridLayout { 101 | width: root.width 102 | rows: 5 103 | 104 | Repeater { 105 | model: ["#727CF5", "#0ACF97", "#F9375E", "#FFBC00", "#2B99B9"] 106 | 107 | Column { 108 | spacing: 15 109 | 110 | RadioButton { 111 | text: "Radio Button 1" 112 | checked: true 113 | checkedColor: modelData 114 | } 115 | 116 | RadioButton { 117 | text: "Radio Button 2" 118 | checkedColor: modelData 119 | } 120 | 121 | RadioButton { 122 | text: "Radio Button 3" 123 | checkedColor: modelData 124 | } 125 | } 126 | } 127 | } 128 | 129 | Text { 130 | text: "Check Box: " 131 | font.pixelSize: 18 132 | font.family: "Arial" 133 | font.weight: Font.Thin 134 | color: "#a0000000" 135 | } 136 | 137 | GridLayout { 138 | width: root.width 139 | rows: 5 140 | 141 | Repeater { 142 | model: ["#727CF5", "#0ACF97", "#F9375E", "#FFBC00", "#2B99B9"] 143 | 144 | Column { 145 | spacing: 15 146 | 147 | CheckBox { 148 | text: "Check Button 1" 149 | checked: true 150 | checkedColor: modelData 151 | } 152 | 153 | CheckBox { 154 | text: "Check Button 2" 155 | checkedColor: modelData 156 | } 157 | 158 | CheckBox { 159 | text: "Check Button 3" 160 | checkedColor: modelData 161 | } 162 | } 163 | } 164 | } 165 | 166 | Text { 167 | text: "Switch: " 168 | font.pixelSize: 18 169 | font.family: "Arial" 170 | font.weight: Font.Thin 171 | color: "#a0000000" 172 | } 173 | 174 | GridLayout { 175 | width: root.width 176 | rows: switchRepeater.count 177 | 178 | Repeater { 179 | id: switchRepeater 180 | model: ["#727CF5", "#0ACF97", "#F9375E", "#FFBC00", "#2B99B9"] 181 | Column { 182 | spacing: 15 183 | Switch { 184 | checkedColor: modelData 185 | checked: true 186 | } 187 | 188 | Switch { 189 | checkedColor: modelData 190 | } 191 | 192 | Switch { 193 | checkedColor: modelData 194 | checked: true 195 | } 196 | } 197 | } 198 | } 199 | 200 | Text { 201 | text: "Text Input: " 202 | font.pixelSize: 18 203 | font.family: "Arial" 204 | font.weight: Font.Thin 205 | color: "#a0000000" 206 | } 207 | 208 | GridLayout { 209 | width: root.width 210 | rows: 3 211 | columns: 3 212 | 213 | Repeater { 214 | id: textFieldRepeater 215 | model: ["#727CF5", "#0ACF97", "#F9375E", 216 | "#FFBC00", "#2B99B9", "#5A6268", 217 | "#EEF2F7", "#212730"] 218 | 219 | TextField { 220 | checkedColor: modelData 221 | } 222 | } 223 | 224 | TextField { 225 | enabled: false 226 | placeholderText: "禁用状态" 227 | } 228 | } 229 | 230 | Text { 231 | text: "ComboBox: " 232 | font.pixelSize: 18 233 | font.family: "Arial" 234 | font.weight: Font.Thin 235 | color: "#a0000000" 236 | } 237 | 238 | GridLayout { 239 | width: root.width 240 | rows: 3 241 | columns: 3 242 | 243 | Repeater { 244 | id: comboboxRepeater 245 | model: ["#727CF5", "#0ACF97", "#F9375E", 246 | "#FFBC00", "#2B99B9", "#5A6268", 247 | "#EEF2F7", "#212730", "#3498DB"] 248 | 249 | ComboBox { 250 | model: ["First", "Second", "Third"] 251 | checkedColor: modelData 252 | } 253 | } 254 | } 255 | 256 | Text { 257 | text: "Slider: " 258 | font.pixelSize: 18 259 | font.family: "Arial" 260 | font.weight: Font.Thin 261 | color: "#a0000000" 262 | } 263 | 264 | GridLayout { 265 | width: root.width 266 | rows: 3 267 | columns: 3 268 | 269 | Repeater { 270 | id: spinBoxRepeater 271 | model: ["#727CF5", "#0ACF97", "#F9375E", 272 | "#FFBC00", "#2B99B9", "#5A6268", 273 | "#EEF2F7", "#212730", "#3498DB"] 274 | 275 | Slider { 276 | checkedColor: modelData 277 | value: Math.random() 278 | } 279 | } 280 | } 281 | 282 | Text { 283 | text: "RangeSlider: " 284 | font.pixelSize: 18 285 | font.family: "Arial" 286 | font.weight: Font.Thin 287 | color: "#a0000000" 288 | } 289 | 290 | GridLayout { 291 | width: root.width 292 | rows: 3 293 | columns: 3 294 | 295 | Repeater { 296 | model: ["#727CF5", "#0ACF97", "#F9375E", 297 | "#FFBC00", "#2B99B9", "#5A6268", 298 | "#EEF2F7", "#212730", "#3498DB"] 299 | 300 | RangeSlider { 301 | checkedColor: modelData 302 | // first.value: Math.random() 303 | // second.value: Math.random() 304 | } 305 | } 306 | } 307 | 308 | Text { 309 | text: "ProgressBar: " 310 | font.pixelSize: 18 311 | font.family: "Arial" 312 | font.weight: Font.Thin 313 | color: "#a0000000" 314 | } 315 | 316 | GridLayout { 317 | width: root.width 318 | rows: 3 319 | columns: 3 320 | 321 | Repeater { 322 | model: ["#727CF5", "#0ACF97", "#F9375E", 323 | "#FFBC00", "#2B99B9", "#5A6268", 324 | "#EEF2F7", "#212730", "#3498DB"] 325 | 326 | ProgressBar { 327 | color: modelData 328 | value: Math.random() 329 | } 330 | } 331 | } 332 | 333 | Text { 334 | text: "SpinBox: " 335 | font.pixelSize: 18 336 | font.family: "Arial" 337 | font.weight: Font.Thin 338 | color: "#a0000000" 339 | } 340 | 341 | GridLayout { 342 | width: root.width 343 | rows: 3 344 | columns: 3 345 | 346 | Repeater { 347 | model: ["#727CF5", "#0ACF97", "#F9375E", 348 | "#FFBC00", "#2B99B9", "#5A6268", 349 | "#EEF2F7", "#212730", "#3498DB"] 350 | 351 | SpinBox { 352 | value: Math.random() * 10 353 | color: modelData 354 | } 355 | } 356 | } 357 | 358 | Text { 359 | text: "Tumbler: " 360 | font.pixelSize: 18 361 | font.family: "Arial" 362 | font.weight: Font.Thin 363 | color: "#a0000000" 364 | } 365 | 366 | GridLayout { 367 | width: root.width 368 | rows: 3 369 | 370 | Repeater { 371 | model: ["#727CF5", "#0ACF97", "#F9375E", 372 | "#FFBC00", "#2B99B9", "#5A6268", 373 | "#EEF2F7", "#212730", "#3498DB"] 374 | 375 | Tumbler { 376 | model: ["00", "01", "02", "03", "04", "05"] 377 | currentItemColor: modelData 378 | } 379 | } 380 | } 381 | } 382 | } 383 | } 384 | -------------------------------------------------------------------------------- /QmlUI/snapshot/demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aeagean/QmlUI/297d646dbe86db7f41163c136f214e92b8aac8fc/QmlUI/snapshot/demo.gif -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![Demo](QmlUI/snapshot/demo.gif) 2 | --------------------------------------------------------------------------------