├── res ├── SBR.jpg ├── Slices.png ├── avatar.png ├── header.png ├── kunkun.png ├── Shizuka.png ├── example.icns ├── example.ico ├── example.png ├── controls │ ├── Grid.png │ ├── Image.png │ ├── Line.png │ ├── Pivot.png │ ├── Shape.png │ ├── Sound.png │ ├── Acrylic.png │ ├── Border.png │ ├── Button.png │ ├── Canvas.png │ ├── Flyout.png │ ├── InfoBar.png │ ├── ListBox.png │ ├── MenuBar.png │ ├── Slider.png │ ├── TabView.png │ ├── TextBox.png │ ├── ToolTip.png │ ├── Viewbox.png │ ├── WebView.png │ ├── Checkbox.png │ ├── Clipboard.png │ ├── ComboBox.png │ ├── CommandBar.png │ ├── DataGrid.png │ ├── DatePicker.png │ ├── Expander.png │ ├── FilePicker.png │ ├── FlipView.png │ ├── GridView.png │ ├── InfoBadge.png │ ├── InkCanvas.png │ ├── InkToolbar.png │ ├── ListView.png │ ├── MenuFlyout.png │ ├── NumberBox.png │ ├── PipsPager.png │ ├── SplitView.png │ ├── StackPanel.png │ ├── TextBlock.png │ ├── TimePicker.png │ ├── TitleBar.png │ ├── TreeView.png │ ├── AnimatedIcon.png │ ├── AppBarButton.png │ ├── CalendarView.png │ ├── ColorPicker.png │ ├── IconElement.png │ ├── ParallaxView.png │ ├── PasswordBox.png │ ├── ProgressBar.png │ ├── ProgressRing.png │ ├── RadioButton.png │ ├── RadioButtons.png │ ├── RepeatButton.png │ ├── RevealFocus.png │ ├── RichEditBox.png │ ├── ScrollViewer.png │ ├── SemanticZoom.png │ ├── SplitButton.png │ ├── SwipeControl.png │ ├── TeachingTip.png │ ├── ToggleButton.png │ ├── ToggleSwitch.png │ ├── AppBarSeparator.png │ ├── AutoSuggestBox.png │ ├── BreadcrumbBar.png │ ├── CompactSizing.png │ ├── ContentDialog.png │ ├── DropDownButton.png │ ├── EasingFunction.png │ ├── HyperlinkButton.png │ ├── InputValidation.png │ ├── ItemsRepeater.png │ ├── NavigationView.png │ ├── PageTransition.png │ ├── PersonPicture.png │ ├── PullToRefresh.png │ ├── RatingControl.png │ ├── RelativePanel.png │ ├── RichTextBlock.png │ ├── ThemeTransition.png │ ├── XamlUICommand.png │ ├── AnimationInterop.png │ ├── CommandBarFlyout.png │ ├── StandardUICommand.png │ ├── ToggleSplitButton.png │ ├── AnimatedVisualPlayer.png │ ├── AppBarToggleButton.png │ ├── AutomationProperties.png │ ├── CalendarDatePicker.png │ ├── ConnectedAnimation.png │ ├── ImplicitTransition.png │ ├── MediaPlayerElement.png │ ├── RadialGradientBrush.png │ ├── ColorPaletteResources.png │ ├── CreateMultipleWindows.png │ └── VariableSizedWrapGrid.png ├── style │ ├── light │ │ ├── view_interface.qss │ │ ├── setting_interface.qss │ │ ├── home_interface.qss │ │ ├── sample_card.qss │ │ ├── navigation_view_interface.qss │ │ ├── link_card.qss │ │ ├── gallery_interface.qss │ │ └── icon_interface.qss │ └── dark │ │ ├── view_interface.qss │ │ ├── setting_interface.qss │ │ ├── home_interface.qss │ │ ├── sample_card.qss │ │ ├── navigation_view_interface.qss │ │ ├── link_card.qss │ │ ├── gallery_interface.qss │ │ └── icon_interface.qss └── icons │ ├── Text_black.svg │ ├── Text_white.svg │ ├── Grid_black.svg │ ├── Grid_white.svg │ ├── EmojiTabSymbols_black.svg │ ├── EmojiTabSymbols_white.svg │ ├── Menu_black.svg │ ├── Menu_white.svg │ ├── Price_black.svg │ └── Price_white.svg ├── version.rc ├── images ├── dark.png └── light.png ├── libs ├── 6.8.3_MSVC │ ├── bin │ │ ├── Debug │ │ │ ├── QFluent.dll │ │ │ ├── QWKCored.dll │ │ │ └── QWKWidgetsd.dll │ │ └── Release │ │ │ ├── QFluent.dll │ │ │ ├── QWKCore.dll │ │ │ └── QWKWidgets.dll │ └── lib │ │ ├── Debug │ │ └── QFluent.lib │ │ └── Release │ │ └── QFluent.lib ├── 5.15.2_MSVC │ ├── bin │ │ ├── Debug │ │ │ ├── QFluent.dll │ │ │ ├── QWKCored.dll │ │ │ └── QWKWidgetsd.dll │ │ └── Release │ │ │ ├── QFluent.dll │ │ │ ├── QWKCore.dll │ │ │ └── QWKWidgets.dll │ └── lib │ │ ├── Debug │ │ └── QFluent.lib │ │ └── Release │ │ └── QFluent.lib └── include │ ├── QFluent │ ├── Loading.h │ ├── menu │ │ ├── ComboBoxMenu.h │ │ ├── MultiViewComboBoxMenu.h │ │ ├── CheckableMenu.h │ │ ├── MenuActionListWidget.h │ │ ├── SubMenuItemWidget.h │ │ ├── RoundMenu.h │ │ ├── MenuAnimation.h │ │ └── MenuItemDelegate.h │ ├── dialog │ │ ├── MessageDialog.h │ │ ├── MessageBoxBase.h │ │ └── MaskDialogBase.h │ ├── ProfileCard.h │ ├── settings │ │ ├── SettingCardGroup.h │ │ └── OptionsSettingCard.h │ ├── progress │ │ ├── ProgressRing.h │ │ ├── ProgressBar.h │ │ ├── IndeterminateProgressBar.h │ │ └── IndeterminateProgressRing.h │ ├── CheckBox.h │ ├── FluentWidget.h │ ├── RadioButton.h │ ├── CardWidget.h │ ├── scrollbar │ │ └── SmoothScroll.h │ ├── layout │ │ ├── ExpandLayout.h │ │ └── FlowLayout.h │ ├── IconWidget.h │ ├── date_time │ │ ├── CalendarPicker.h │ │ ├── CycleListWidget.h │ │ ├── TimePicker.h │ │ └── DatePicker.h │ ├── FluentSplitWindow.h │ ├── FluentWindow.h │ ├── FluentTitleBar.h │ ├── TextEdit.h │ ├── MultiViewComboBox.h │ ├── ScrollArea.h │ ├── ComboBox.h │ ├── EditableComboBox.h │ ├── Label.h │ ├── navigation │ │ └── Pivot.h │ ├── SwitchButton.h │ ├── PagiNation.h │ ├── AvatarWidget.h │ ├── StackedWidget.h │ └── Slider.h │ ├── Screen.h │ ├── TextWrap.h │ ├── Theme.h │ └── Router.h ├── src ├── TextInterface.h ├── ScrollInterface.h ├── WindowInterface.h ├── BasicInputInterface.h ├── DateTimeInputInterface.h ├── MainWindow.h ├── LayoutInterface.h ├── StatusInfoInterface.h ├── Window │ ├── NavbarWindow.h │ ├── SplitWindow.h │ ├── LoginWindow.h │ ├── SplitWindow.cpp │ ├── NavbarWindow.cpp │ └── LoginWindow.cpp ├── DialogInputInterface.h ├── ScrollInterface.cpp ├── SettingInterface.h ├── ViewInterface.h ├── MenuInterface.h ├── NavigationViewInterface.h ├── main.cpp ├── DateTimeInputInterface.cpp ├── HomeInterface.h ├── LayoutInterface.cpp ├── Card │ ├── LinkCard.h │ ├── SampleCard.h │ ├── LinkCard.cpp │ └── SampleCard.cpp ├── WindowInterface.cpp ├── FluentWindow.h.txt ├── TextInterface.cpp ├── GalleryInterface.h ├── NavigationViewInterface.cpp ├── ConfigManager.h ├── IconInterface.h ├── MainWindow.cpp └── StatusInfoInterface.cpp ├── .gitignore ├── README.md ├── LICENSE └── CMakeLists.txt /res/SBR.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/SBR.jpg -------------------------------------------------------------------------------- /version.rc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/version.rc -------------------------------------------------------------------------------- /res/Slices.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/Slices.png -------------------------------------------------------------------------------- /res/avatar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/avatar.png -------------------------------------------------------------------------------- /res/header.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/header.png -------------------------------------------------------------------------------- /res/kunkun.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/kunkun.png -------------------------------------------------------------------------------- /images/dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/images/dark.png -------------------------------------------------------------------------------- /images/light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/images/light.png -------------------------------------------------------------------------------- /res/Shizuka.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/Shizuka.png -------------------------------------------------------------------------------- /res/example.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/example.icns -------------------------------------------------------------------------------- /res/example.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/example.ico -------------------------------------------------------------------------------- /res/example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/example.png -------------------------------------------------------------------------------- /res/controls/Grid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/Grid.png -------------------------------------------------------------------------------- /res/controls/Image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/Image.png -------------------------------------------------------------------------------- /res/controls/Line.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/Line.png -------------------------------------------------------------------------------- /res/controls/Pivot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/Pivot.png -------------------------------------------------------------------------------- /res/controls/Shape.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/Shape.png -------------------------------------------------------------------------------- /res/controls/Sound.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/Sound.png -------------------------------------------------------------------------------- /res/controls/Acrylic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/Acrylic.png -------------------------------------------------------------------------------- /res/controls/Border.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/Border.png -------------------------------------------------------------------------------- /res/controls/Button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/Button.png -------------------------------------------------------------------------------- /res/controls/Canvas.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/Canvas.png -------------------------------------------------------------------------------- /res/controls/Flyout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/Flyout.png -------------------------------------------------------------------------------- /res/controls/InfoBar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/InfoBar.png -------------------------------------------------------------------------------- /res/controls/ListBox.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/ListBox.png -------------------------------------------------------------------------------- /res/controls/MenuBar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/MenuBar.png -------------------------------------------------------------------------------- /res/controls/Slider.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/Slider.png -------------------------------------------------------------------------------- /res/controls/TabView.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/TabView.png -------------------------------------------------------------------------------- /res/controls/TextBox.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/TextBox.png -------------------------------------------------------------------------------- /res/controls/ToolTip.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/ToolTip.png -------------------------------------------------------------------------------- /res/controls/Viewbox.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/Viewbox.png -------------------------------------------------------------------------------- /res/controls/WebView.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/WebView.png -------------------------------------------------------------------------------- /res/controls/Checkbox.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/Checkbox.png -------------------------------------------------------------------------------- /res/controls/Clipboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/Clipboard.png -------------------------------------------------------------------------------- /res/controls/ComboBox.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/ComboBox.png -------------------------------------------------------------------------------- /res/controls/CommandBar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/CommandBar.png -------------------------------------------------------------------------------- /res/controls/DataGrid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/DataGrid.png -------------------------------------------------------------------------------- /res/controls/DatePicker.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/DatePicker.png -------------------------------------------------------------------------------- /res/controls/Expander.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/Expander.png -------------------------------------------------------------------------------- /res/controls/FilePicker.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/FilePicker.png -------------------------------------------------------------------------------- /res/controls/FlipView.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/FlipView.png -------------------------------------------------------------------------------- /res/controls/GridView.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/GridView.png -------------------------------------------------------------------------------- /res/controls/InfoBadge.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/InfoBadge.png -------------------------------------------------------------------------------- /res/controls/InkCanvas.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/InkCanvas.png -------------------------------------------------------------------------------- /res/controls/InkToolbar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/InkToolbar.png -------------------------------------------------------------------------------- /res/controls/ListView.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/ListView.png -------------------------------------------------------------------------------- /res/controls/MenuFlyout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/MenuFlyout.png -------------------------------------------------------------------------------- /res/controls/NumberBox.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/NumberBox.png -------------------------------------------------------------------------------- /res/controls/PipsPager.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/PipsPager.png -------------------------------------------------------------------------------- /res/controls/SplitView.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/SplitView.png -------------------------------------------------------------------------------- /res/controls/StackPanel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/StackPanel.png -------------------------------------------------------------------------------- /res/controls/TextBlock.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/TextBlock.png -------------------------------------------------------------------------------- /res/controls/TimePicker.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/TimePicker.png -------------------------------------------------------------------------------- /res/controls/TitleBar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/TitleBar.png -------------------------------------------------------------------------------- /res/controls/TreeView.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/TreeView.png -------------------------------------------------------------------------------- /res/controls/AnimatedIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/AnimatedIcon.png -------------------------------------------------------------------------------- /res/controls/AppBarButton.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/AppBarButton.png -------------------------------------------------------------------------------- /res/controls/CalendarView.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/CalendarView.png -------------------------------------------------------------------------------- /res/controls/ColorPicker.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/ColorPicker.png -------------------------------------------------------------------------------- /res/controls/IconElement.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/IconElement.png -------------------------------------------------------------------------------- /res/controls/ParallaxView.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/ParallaxView.png -------------------------------------------------------------------------------- /res/controls/PasswordBox.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/PasswordBox.png -------------------------------------------------------------------------------- /res/controls/ProgressBar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/ProgressBar.png -------------------------------------------------------------------------------- /res/controls/ProgressRing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/ProgressRing.png -------------------------------------------------------------------------------- /res/controls/RadioButton.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/RadioButton.png -------------------------------------------------------------------------------- /res/controls/RadioButtons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/RadioButtons.png -------------------------------------------------------------------------------- /res/controls/RepeatButton.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/RepeatButton.png -------------------------------------------------------------------------------- /res/controls/RevealFocus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/RevealFocus.png -------------------------------------------------------------------------------- /res/controls/RichEditBox.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/RichEditBox.png -------------------------------------------------------------------------------- /res/controls/ScrollViewer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/ScrollViewer.png -------------------------------------------------------------------------------- /res/controls/SemanticZoom.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/SemanticZoom.png -------------------------------------------------------------------------------- /res/controls/SplitButton.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/SplitButton.png -------------------------------------------------------------------------------- /res/controls/SwipeControl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/SwipeControl.png -------------------------------------------------------------------------------- /res/controls/TeachingTip.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/TeachingTip.png -------------------------------------------------------------------------------- /res/controls/ToggleButton.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/ToggleButton.png -------------------------------------------------------------------------------- /res/controls/ToggleSwitch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/ToggleSwitch.png -------------------------------------------------------------------------------- /res/controls/AppBarSeparator.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/AppBarSeparator.png -------------------------------------------------------------------------------- /res/controls/AutoSuggestBox.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/AutoSuggestBox.png -------------------------------------------------------------------------------- /res/controls/BreadcrumbBar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/BreadcrumbBar.png -------------------------------------------------------------------------------- /res/controls/CompactSizing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/CompactSizing.png -------------------------------------------------------------------------------- /res/controls/ContentDialog.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/ContentDialog.png -------------------------------------------------------------------------------- /res/controls/DropDownButton.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/DropDownButton.png -------------------------------------------------------------------------------- /res/controls/EasingFunction.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/EasingFunction.png -------------------------------------------------------------------------------- /res/controls/HyperlinkButton.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/HyperlinkButton.png -------------------------------------------------------------------------------- /res/controls/InputValidation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/InputValidation.png -------------------------------------------------------------------------------- /res/controls/ItemsRepeater.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/ItemsRepeater.png -------------------------------------------------------------------------------- /res/controls/NavigationView.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/NavigationView.png -------------------------------------------------------------------------------- /res/controls/PageTransition.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/PageTransition.png -------------------------------------------------------------------------------- /res/controls/PersonPicture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/PersonPicture.png -------------------------------------------------------------------------------- /res/controls/PullToRefresh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/PullToRefresh.png -------------------------------------------------------------------------------- /res/controls/RatingControl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/RatingControl.png -------------------------------------------------------------------------------- /res/controls/RelativePanel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/RelativePanel.png -------------------------------------------------------------------------------- /res/controls/RichTextBlock.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/RichTextBlock.png -------------------------------------------------------------------------------- /res/controls/ThemeTransition.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/ThemeTransition.png -------------------------------------------------------------------------------- /res/controls/XamlUICommand.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/XamlUICommand.png -------------------------------------------------------------------------------- /res/controls/AnimationInterop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/AnimationInterop.png -------------------------------------------------------------------------------- /res/controls/CommandBarFlyout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/CommandBarFlyout.png -------------------------------------------------------------------------------- /res/controls/StandardUICommand.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/StandardUICommand.png -------------------------------------------------------------------------------- /res/controls/ToggleSplitButton.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/ToggleSplitButton.png -------------------------------------------------------------------------------- /libs/6.8.3_MSVC/bin/Debug/QFluent.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/libs/6.8.3_MSVC/bin/Debug/QFluent.dll -------------------------------------------------------------------------------- /libs/6.8.3_MSVC/lib/Debug/QFluent.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/libs/6.8.3_MSVC/lib/Debug/QFluent.lib -------------------------------------------------------------------------------- /res/controls/AnimatedVisualPlayer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/AnimatedVisualPlayer.png -------------------------------------------------------------------------------- /res/controls/AppBarToggleButton.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/AppBarToggleButton.png -------------------------------------------------------------------------------- /res/controls/AutomationProperties.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/AutomationProperties.png -------------------------------------------------------------------------------- /res/controls/CalendarDatePicker.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/CalendarDatePicker.png -------------------------------------------------------------------------------- /res/controls/ConnectedAnimation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/ConnectedAnimation.png -------------------------------------------------------------------------------- /res/controls/ImplicitTransition.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/ImplicitTransition.png -------------------------------------------------------------------------------- /res/controls/MediaPlayerElement.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/MediaPlayerElement.png -------------------------------------------------------------------------------- /res/controls/RadialGradientBrush.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/RadialGradientBrush.png -------------------------------------------------------------------------------- /libs/5.15.2_MSVC/bin/Debug/QFluent.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/libs/5.15.2_MSVC/bin/Debug/QFluent.dll -------------------------------------------------------------------------------- /libs/5.15.2_MSVC/bin/Debug/QWKCored.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/libs/5.15.2_MSVC/bin/Debug/QWKCored.dll -------------------------------------------------------------------------------- /libs/5.15.2_MSVC/lib/Debug/QFluent.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/libs/5.15.2_MSVC/lib/Debug/QFluent.lib -------------------------------------------------------------------------------- /libs/6.8.3_MSVC/bin/Debug/QWKCored.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/libs/6.8.3_MSVC/bin/Debug/QWKCored.dll -------------------------------------------------------------------------------- /libs/6.8.3_MSVC/bin/Release/QFluent.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/libs/6.8.3_MSVC/bin/Release/QFluent.dll -------------------------------------------------------------------------------- /libs/6.8.3_MSVC/bin/Release/QWKCore.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/libs/6.8.3_MSVC/bin/Release/QWKCore.dll -------------------------------------------------------------------------------- /libs/6.8.3_MSVC/lib/Release/QFluent.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/libs/6.8.3_MSVC/lib/Release/QFluent.lib -------------------------------------------------------------------------------- /res/controls/ColorPaletteResources.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/ColorPaletteResources.png -------------------------------------------------------------------------------- /res/controls/CreateMultipleWindows.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/CreateMultipleWindows.png -------------------------------------------------------------------------------- /res/controls/VariableSizedWrapGrid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/res/controls/VariableSizedWrapGrid.png -------------------------------------------------------------------------------- /libs/5.15.2_MSVC/bin/Debug/QWKWidgetsd.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/libs/5.15.2_MSVC/bin/Debug/QWKWidgetsd.dll -------------------------------------------------------------------------------- /libs/5.15.2_MSVC/bin/Release/QFluent.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/libs/5.15.2_MSVC/bin/Release/QFluent.dll -------------------------------------------------------------------------------- /libs/5.15.2_MSVC/bin/Release/QWKCore.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/libs/5.15.2_MSVC/bin/Release/QWKCore.dll -------------------------------------------------------------------------------- /libs/5.15.2_MSVC/lib/Release/QFluent.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/libs/5.15.2_MSVC/lib/Release/QFluent.lib -------------------------------------------------------------------------------- /libs/6.8.3_MSVC/bin/Debug/QWKWidgetsd.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/libs/6.8.3_MSVC/bin/Debug/QWKWidgetsd.dll -------------------------------------------------------------------------------- /libs/6.8.3_MSVC/bin/Release/QWKWidgets.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/libs/6.8.3_MSVC/bin/Release/QWKWidgets.dll -------------------------------------------------------------------------------- /libs/5.15.2_MSVC/bin/Release/QWKWidgets.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddming/QFluentExample/HEAD/libs/5.15.2_MSVC/bin/Release/QWKWidgets.dll -------------------------------------------------------------------------------- /res/style/light/view_interface.qss: -------------------------------------------------------------------------------- 1 | #frame { 2 | border: 1px solid rgba(0, 0, 0, 15); 3 | border-radius: 5px; 4 | background-color: transparent; 5 | } -------------------------------------------------------------------------------- /res/style/dark/view_interface.qss: -------------------------------------------------------------------------------- 1 | #frame { 2 | border: 1px solid rgba(255, 255, 255, 13); 3 | border-radius: 5px; 4 | background-color: transparent; 5 | } -------------------------------------------------------------------------------- /src/TextInterface.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "GalleryInterface.h" 4 | 5 | class TextInterface : public GalleryInterface 6 | { 7 | Q_OBJECT 8 | public: 9 | explicit TextInterface(QWidget *parent = nullptr); 10 | 11 | 12 | }; 13 | -------------------------------------------------------------------------------- /src/ScrollInterface.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "GalleryInterface.h" 4 | 5 | class ScrollInterface : public GalleryInterface 6 | { 7 | Q_OBJECT 8 | public: 9 | explicit ScrollInterface(QWidget *parent = nullptr); 10 | 11 | 12 | }; 13 | -------------------------------------------------------------------------------- /src/WindowInterface.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "GalleryInterface.h" 4 | 5 | class WindowInterface : public GalleryInterface 6 | { 7 | Q_OBJECT 8 | public: 9 | explicit WindowInterface(QWidget *parent = nullptr); 10 | 11 | 12 | }; 13 | -------------------------------------------------------------------------------- /src/BasicInputInterface.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "GalleryInterface.h" 4 | 5 | class BasicInputInterface : public GalleryInterface 6 | { 7 | Q_OBJECT 8 | public: 9 | explicit BasicInputInterface(QWidget *parent = nullptr); 10 | 11 | }; 12 | -------------------------------------------------------------------------------- /src/DateTimeInputInterface.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "GalleryInterface.h" 4 | 5 | class DateTimeInputInterface : public GalleryInterface 6 | { 7 | Q_OBJECT 8 | public: 9 | explicit DateTimeInputInterface(QWidget *parent = nullptr); 10 | 11 | }; 12 | -------------------------------------------------------------------------------- /src/MainWindow.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "QFluent/FluentWindow.h" 4 | 5 | 6 | class MainWindow : public FluentWindow { 7 | Q_OBJECT 8 | public: 9 | explicit MainWindow(); 10 | 11 | void setCurrentInterface(const QString &routeKey, int index); 12 | }; 13 | -------------------------------------------------------------------------------- /libs/include/QFluent/Loading.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "dialog/MaskDialogBase.h" 4 | #include "FluentGlobal.h" 5 | 6 | class QFLUENT_EXPORT Loading : public MaskDialogBase 7 | { 8 | Q_OBJECT 9 | public: 10 | explicit Loading(const QString &content = QString(), QWidget *parent = nullptr); 11 | 12 | }; 13 | -------------------------------------------------------------------------------- /src/LayoutInterface.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "GalleryInterface.h" 4 | 5 | class LayoutInterface : public GalleryInterface 6 | { 7 | Q_OBJECT 8 | public: 9 | explicit LayoutInterface(QWidget *parent = nullptr); 10 | 11 | private: 12 | QWidget *createWidget(bool animation = false); 13 | 14 | }; 15 | -------------------------------------------------------------------------------- /src/StatusInfoInterface.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "GalleryInterface.h" 5 | 6 | class StatusInfoInterface : public GalleryInterface 7 | { 8 | Q_OBJECT 9 | public: 10 | explicit StatusInfoInterface(QWidget *parent = nullptr); 11 | 12 | private: 13 | QWidget* createProgressWidget(QProgressBar *widget); 14 | }; 15 | -------------------------------------------------------------------------------- /res/style/light/setting_interface.qss: -------------------------------------------------------------------------------- 1 | SettingInterface, #scrollWidget { 2 | background-color: transparent; 3 | } 4 | 5 | QScrollArea { 6 | background-color: transparent; 7 | border: none; 8 | } 9 | 10 | 11 | /* 标签 */ 12 | QLabel#settingLabel { 13 | font: 33px 'Microsoft YaHei'; 14 | background-color: transparent; 15 | color: black; 16 | } 17 | -------------------------------------------------------------------------------- /src/Window/NavbarWindow.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "QFluent/FluentWidget.h" 6 | 7 | class NavbarWidget : public FluentWidget 8 | { 9 | Q_OBJECT 10 | public: 11 | explicit NavbarWidget(); 12 | 13 | private: 14 | void initUI(); 15 | 16 | QWidget* createWidget(const QString &text, QWidget* parent); 17 | 18 | }; 19 | 20 | -------------------------------------------------------------------------------- /res/style/dark/setting_interface.qss: -------------------------------------------------------------------------------- 1 | SettingInterface, #scrollWidget { 2 | background-color: transparent; 3 | } 4 | 5 | QScrollArea { 6 | border: none; 7 | background-color: transparent; 8 | } 9 | 10 | 11 | /* 标签 */ 12 | QLabel#settingLabel { 13 | font: 33px 'Microsoft YaHei'; 14 | background-color: transparent; 15 | color: white; 16 | } 17 | 18 | -------------------------------------------------------------------------------- /src/Window/SplitWindow.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "QFluent/FluentSplitWindow.h" 6 | 7 | class SplitWidget : public FluentSplitWindow 8 | { 9 | Q_OBJECT 10 | public: 11 | explicit SplitWidget(); 12 | 13 | private: 14 | void initUI(); 15 | 16 | QWidget* createWidget(const QString &text, QWidget* parent); 17 | 18 | }; 19 | 20 | -------------------------------------------------------------------------------- /libs/include/QFluent/menu/ComboBoxMenu.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "RoundMenu.h" 4 | 5 | class ComboBoxMenu : public RoundMenu 6 | { 7 | public: 8 | explicit ComboBoxMenu(const QString& title = "", QWidget *parent = nullptr); 9 | 10 | void exec(const QPoint& pos, bool animate = true, 11 | Fluent::MenuAnimation aniType = Fluent::MenuAnimation::DROP_DOWN); 12 | 13 | }; 14 | -------------------------------------------------------------------------------- /res/style/dark/home_interface.qss: -------------------------------------------------------------------------------- 1 | SettingInterface, 2 | #view { 3 | background-color: transparent; 4 | } 5 | 6 | QScrollArea { 7 | border: none; 8 | background-color: transparent; 9 | } 10 | 11 | 12 | BannerWidget > #galleryLabel { 13 | font: 42px 'Segoe UI SemiBold', 'Microsoft YaHei SemiBold'; 14 | background-color: transparent; 15 | color: white; 16 | padding-left: 28px; 17 | } 18 | -------------------------------------------------------------------------------- /res/style/dark/sample_card.qss: -------------------------------------------------------------------------------- 1 | #titleLabel { 2 | color: white; 3 | font: 14px 'Segoe UI', 'Microsoft YaHei', 'PingFang SC'; 4 | font-weight: bold; 5 | } 6 | 7 | #contentLabel { 8 | color: rgb(208, 208, 208); 9 | font: 12px 'Segoe UI', 'Microsoft YaHei', 'PingFang SC'; 10 | } 11 | 12 | #viewTitleLabel { 13 | color: white; 14 | font: 20px "Segoe UI SemiBold", "Microsoft YaHei", 'PingFang SC'; 15 | } -------------------------------------------------------------------------------- /res/style/light/home_interface.qss: -------------------------------------------------------------------------------- 1 | SettingInterface, 2 | #view { 3 | background-color: transparent; 4 | } 5 | 6 | QScrollArea { 7 | border: none; 8 | background-color: transparent; 9 | } 10 | 11 | 12 | BannerWidget > #galleryLabel { 13 | font: 42px 'Segoe UI SemiBold', 'Microsoft YaHei SemiBold'; 14 | background-color: transparent; 15 | color: black; 16 | padding-left: 28px; 17 | } 18 | 19 | 20 | -------------------------------------------------------------------------------- /res/style/light/sample_card.qss: -------------------------------------------------------------------------------- 1 | #titleLabel { 2 | color: black; 3 | font: 14px 'Segoe UI', 'Microsoft YaHei', 'PingFang SC'; 4 | font-weight: bold; 5 | } 6 | 7 | #contentLabel { 8 | color: rgb(118, 118, 118); 9 | font: 12px 'Segoe UI', 'Microsoft YaHei', 'PingFang SC'; 10 | } 11 | 12 | #viewTitleLabel { 13 | color: black; 14 | font: 20px "Segoe UI SemiBold", "Microsoft YaHei", 'PingFang SC'; 15 | } -------------------------------------------------------------------------------- /res/style/light/navigation_view_interface.qss: -------------------------------------------------------------------------------- 1 | PivotInterface QLabel, 2 | TabInterface QLabel { 3 | padding-left: 10px; 4 | font: 14px 'Segoe UI', 'Microsoft YaHei', 'PingFang SC'; 5 | color: black; 6 | } 7 | 8 | #controlPanel BodyLabel { 9 | padding-left: 0px; 10 | } 11 | 12 | #controlPanel { 13 | background-color: white; 14 | border-left: 1px solid rgb(229, 229, 229); 15 | border-top-right-radius: 10px; 16 | } -------------------------------------------------------------------------------- /res/style/dark/navigation_view_interface.qss: -------------------------------------------------------------------------------- 1 | PivotInterface QLabel, 2 | TabInterface QLabel { 3 | padding-left: 10px; 4 | font: 14px 'Segoe UI', 'Microsoft YaHei', 'PingFang SC'; 5 | color: white; 6 | } 7 | 8 | #controlPanel BodyLabel { 9 | padding-left: 0px; 10 | } 11 | 12 | #controlPanel { 13 | background-color: rgb(43, 43, 43); 14 | border-left: 1px solid rgb(50, 50, 50); 15 | border-top-right-radius: 10px; 16 | } -------------------------------------------------------------------------------- /src/DialogInputInterface.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "GalleryInterface.h" 4 | 5 | class DialogInputInterface : public GalleryInterface 6 | { 7 | Q_OBJECT 8 | public: 9 | explicit DialogInputInterface(QWidget *parent = nullptr); 10 | 11 | private slots: 12 | void showSimpleFlyout(QWidget* target); 13 | void showComplexFlyout(QWidget* target); 14 | void showBottomTeachingTip(QWidget* target); 15 | void showLeftBottomTeachingTip(QWidget* target); 16 | }; 17 | -------------------------------------------------------------------------------- /src/ScrollInterface.cpp: -------------------------------------------------------------------------------- 1 | #include "ScrollInterface.h" 2 | 3 | #include "QFluent/PagiNation.h" 4 | 5 | ScrollInterface::ScrollInterface(QWidget *parent) 6 | : GalleryInterface("滚动", "", parent) 7 | { 8 | setObjectName("ScrollInterface"); 9 | 10 | auto pagiNation = new PagiNation(this); 11 | pagiNation->setAlign(Fluent::Alignment::Align_Left); 12 | pagiNation->setPageSize(10); 13 | pagiNation->setTotal(500); 14 | addExampleCard("页码", pagiNation); 15 | } 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/SettingInterface.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "QFluent/ScrollArea.h" 4 | #include "QFluent/layout/ExpandLayout.h" 5 | #include "QFluent/dialog/ColorDialog.h" 6 | 7 | class SettingInterface : public ScrollArea 8 | { 9 | Q_OBJECT 10 | public: 11 | explicit SettingInterface(QWidget *parent = nullptr); 12 | 13 | private: 14 | QWidget *m_scrollWidget; 15 | ExpandLayout *m_expandLayout; 16 | ColorDialog *m_colorDialog{nullptr}; 17 | 18 | void initConf(); 19 | }; 20 | -------------------------------------------------------------------------------- /libs/include/QFluent/menu/MultiViewComboBoxMenu.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "RoundMenu.h" 4 | 5 | class MultiViewComboBoxMenu : public RoundMenu 6 | { 7 | public: 8 | explicit MultiViewComboBoxMenu(const QString& title = "", QWidget *parent = nullptr); 9 | 10 | void exec(const QPoint& pos, bool animate = true, 11 | Fluent::MenuAnimation aniType = Fluent::MenuAnimation::DROP_DOWN); 12 | 13 | protected: 14 | int adjustItemText(QListWidgetItem *item, QAction *action) override; 15 | }; 16 | -------------------------------------------------------------------------------- /libs/include/QFluent/menu/CheckableMenu.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "RoundMenu.h" 4 | 5 | class QAction; 6 | class QListWidgetItem; 7 | class QFLUENT_EXPORT CheckableMenu : public RoundMenu { 8 | Q_OBJECT 9 | 10 | public: 11 | explicit CheckableMenu(const QString& title = "", QWidget* parent = nullptr, 12 | Fluent::MenuIndicator indicatorType = Fluent::MenuIndicator::CHECK); 13 | 14 | protected: 15 | int adjustItemText(QListWidgetItem *item, QAction *action) override; 16 | }; 17 | -------------------------------------------------------------------------------- /libs/include/Screen.h: -------------------------------------------------------------------------------- 1 | #ifndef SCREEN_H 2 | #define SCREEN_H 3 | 4 | #include 5 | 6 | class QScreen; 7 | class Screen 8 | { 9 | public: 10 | /** 11 | * @brief 获取当前鼠标所在的屏幕 12 | * @return QScreen* 如果找到,否则返回主屏幕 13 | */ 14 | static QScreen* getCurrentScreen(); 15 | 16 | /** 17 | * @brief 获取当前屏幕的几何区域 18 | * @param available 是否返回可用区域(避开任务栏等),默认 true 19 | * @return 屏幕的 QRect 区域 20 | */ 21 | static QRect getCurrentScreenGeometry(bool available = true); 22 | }; 23 | 24 | #endif // SCREEN_H 25 | -------------------------------------------------------------------------------- /src/ViewInterface.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "GalleryInterface.h" 4 | 5 | class Frame : public QFrame 6 | { 7 | Q_OBJECT 8 | 9 | public: 10 | explicit Frame(QWidget *parent = nullptr); 11 | 12 | void addWidget(QWidget *widget); 13 | 14 | private: 15 | QHBoxLayout *hBoxLayout; 16 | void setupUI(); 17 | void applyStyleSheet(); 18 | }; 19 | 20 | 21 | class ViewInterface : public GalleryInterface 22 | { 23 | Q_OBJECT 24 | public: 25 | explicit ViewInterface(QWidget *parent = nullptr); 26 | 27 | 28 | }; 29 | -------------------------------------------------------------------------------- /src/MenuInterface.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "GalleryInterface.h" 4 | 5 | class MenuInterface : public GalleryInterface 6 | { 7 | Q_OBJECT 8 | public: 9 | explicit MenuInterface(QWidget *parent = nullptr); 10 | 11 | private: 12 | Action* createTimeAction; 13 | Action* shootTimeAction; 14 | Action* modifiedTimeAction; 15 | Action* nameAction; 16 | Action* ascendAction; 17 | Action* descendAction; 18 | 19 | void createMenu(QPoint pos); 20 | void createCustomWidgetMenu(QPoint pos); 21 | void createCheckableMenu(QPoint pos); 22 | }; 23 | -------------------------------------------------------------------------------- /src/NavigationViewInterface.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "GalleryInterface.h" 4 | #include "QFluent/TabBar.h" 5 | #include "QFluent/StackedWidget.h" 6 | 7 | class NavigationViewInterface : public GalleryInterface 8 | { 9 | Q_OBJECT 10 | public: 11 | explicit NavigationViewInterface(QWidget *parent = nullptr); 12 | 13 | private: 14 | QWidget* createTabWidget(); 15 | 16 | void addTab(); 17 | void removeTab(int index); 18 | 19 | TabBar* tabBar; 20 | StackedWidget* stacked; 21 | 22 | QMap tabMap; 23 | 24 | int tabCount = 0; 25 | }; 26 | -------------------------------------------------------------------------------- /libs/include/QFluent/dialog/MessageDialog.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "MaskDialogBase.h" 4 | #include "FluentGlobal.h" 5 | 6 | class QEvent; 7 | class MessageDialogPrivate; 8 | class QFLUENT_EXPORT MessageDialog : public MaskDialogBase 9 | { 10 | Q_OBJECT 11 | Q_DECLARE_PRIVATE(MessageDialog) 12 | 13 | public: 14 | explicit MessageDialog(const QString &title, const QString &content, QWidget *parent = nullptr); 15 | ~MessageDialog(); 16 | 17 | signals: 18 | void yesClicked(); 19 | void cancelClicked(); 20 | 21 | protected: 22 | bool eventFilter(QObject *watched, QEvent *event) override; 23 | 24 | }; 25 | -------------------------------------------------------------------------------- /libs/include/QFluent/dialog/MessageBoxBase.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "MaskDialogBase.h" 4 | #include "FluentGlobal.h" 5 | 6 | class QEvent; 7 | class QPushButton; 8 | class QVBoxLayout; 9 | class MessageBoxBasePrivate; 10 | class QFLUENT_EXPORT MessageBoxBase : public MaskDialogBase 11 | { 12 | Q_OBJECT 13 | Q_DECLARE_PRIVATE(MessageBoxBase) 14 | 15 | public: 16 | explicit MessageBoxBase(QWidget *parent = nullptr); 17 | ~MessageBoxBase(); 18 | 19 | QVBoxLayout* viewLayout(); 20 | 21 | void hideYesButton(); 22 | void hideCancelButton(); 23 | 24 | QPushButton* yesButton(); 25 | QPushButton* cancelbutton(); 26 | 27 | }; 28 | -------------------------------------------------------------------------------- /res/style/dark/link_card.qss: -------------------------------------------------------------------------------- 1 | LinkCard { 2 | border: 1px solid rgb(46, 46, 46); 3 | border-radius: 10px; 4 | background-color: rgba(39, 39, 39, 0.95); 5 | } 6 | 7 | LinkCard:hover { 8 | background-color: rgba(39, 39, 39, 0.93); 9 | border: 1px solid rgb(66, 66, 66); 10 | } 11 | 12 | #titleLabel { 13 | font: 18px 'Segoe UI', 'Microsoft YaHei', 'PingFang SC'; 14 | color: white; 15 | } 16 | 17 | #contentLabel { 18 | font: 12px 'Segoe UI', 'Microsoft YaHei', 'PingFang SC'; 19 | color: rgb(208, 208, 208); 20 | } 21 | 22 | LinkCardView { 23 | background-color: transparent; 24 | border: none; 25 | } 26 | 27 | #view { 28 | background-color: transparent; 29 | } -------------------------------------------------------------------------------- /res/style/light/link_card.qss: -------------------------------------------------------------------------------- 1 | LinkCard { 2 | border: 1px solid rgb(234, 234, 234); 3 | border-radius: 10px; 4 | background-color: rgba(249, 249, 249, 0.95); 5 | } 6 | 7 | LinkCard:hover { 8 | background-color: rgba(249, 249, 249, 0.93); 9 | border: 1px solid rgb(220, 220, 220); 10 | } 11 | 12 | #titleLabel { 13 | font: 18px 'Segoe UI', 'Microsoft YaHei', 'PingFang SC'; 14 | color: black; 15 | } 16 | 17 | #contentLabel { 18 | font: 12px 'Segoe UI', 'Microsoft YaHei', 'PingFang SC'; 19 | color: rgb(93, 93, 93); 20 | } 21 | 22 | LinkCardView { 23 | background-color: transparent; 24 | border: none; 25 | } 26 | 27 | #view { 28 | background-color: transparent; 29 | } -------------------------------------------------------------------------------- /libs/include/QFluent/ProfileCard.h: -------------------------------------------------------------------------------- 1 | #ifndef PROFILECARD_H 2 | #define PROFILECARD_H 3 | 4 | #include 5 | #include "FluentGlobal.h" 6 | 7 | class BodyLabel; 8 | class CaptionLabel; 9 | class AvatarWidget; 10 | class HyperlinkButton; 11 | class QFLUENT_EXPORT ProfileCard : public QWidget 12 | { 13 | Q_OBJECT 14 | 15 | public: 16 | explicit ProfileCard(const QString& avatarPath, 17 | const QString& name, 18 | const QString& email, 19 | QWidget *parent = nullptr); 20 | 21 | private: 22 | AvatarWidget *avatar; 23 | BodyLabel *nameLabel; 24 | CaptionLabel *emailLabel; 25 | HyperlinkButton *logoutButton; 26 | }; 27 | 28 | #endif // PROFILECARD_H 29 | -------------------------------------------------------------------------------- /libs/include/QFluent/settings/SettingCardGroup.h: -------------------------------------------------------------------------------- 1 | #ifndef SETTINGCARDGROUP_H 2 | #define SETTINGCARDGROUP_H 3 | 4 | #include 5 | 6 | #include "FluentGlobal.h" 7 | #include "../layout/ExpandLayout.h" 8 | 9 | class QLabel; 10 | class QVBoxLayout; 11 | class QFLUENT_EXPORT SettingCardGroup : public QWidget 12 | { 13 | Q_OBJECT 14 | 15 | public: 16 | explicit SettingCardGroup(const QString &title, QWidget *parent = nullptr); 17 | 18 | void addSettingCard(QWidget *card); 19 | void addSettingCards(const QList &cards); 20 | 21 | void adjustSize(); 22 | 23 | private: 24 | QLabel *titleLabel; 25 | QVBoxLayout *vBoxLayout; 26 | ExpandLayout *cardLayout; 27 | }; 28 | 29 | #endif // SETTINGCARDGROUP_H 30 | -------------------------------------------------------------------------------- /libs/include/TextWrap.h: -------------------------------------------------------------------------------- 1 | #ifndef TEXTWRAP_H 2 | #define TEXTWRAP_H 3 | 4 | #include 5 | #include 6 | 7 | #include "FluentGlobal.h" 8 | 9 | class TextWrapPrivate; 10 | 11 | class QFLUENT_EXPORT TextWrap 12 | { 13 | public: 14 | static std::pair wrap(const QString &text, int width, bool once = true); 15 | 16 | // 可选:设置缓存大小(单位:条目数) 17 | static void setCacheSize(int size); 18 | static void clearCache(); // 清空缓存 19 | 20 | private: 21 | Q_DISABLE_COPY(TextWrap) 22 | Q_DECLARE_PRIVATE(TextWrap) 23 | 24 | TextWrap(); 25 | ~TextWrap(); 26 | 27 | // 获取单例实例 28 | static TextWrap* instance(); 29 | 30 | QScopedPointer d_ptr; 31 | }; 32 | 33 | #endif // TEXTWRAP_H 34 | -------------------------------------------------------------------------------- /src/Window/LoginWindow.h: -------------------------------------------------------------------------------- 1 | #ifndef LOGINWIDGET_H 2 | #define LOGINWIDGET_H 3 | 4 | #include 5 | 6 | #include "QFluent/Loading.h" 7 | #include "QFluent/LineEdit.h" 8 | #include "QFluent/CheckBox.h" 9 | #include "QFluent/PushButton.h" 10 | #include "QFluent/FluentWidget.h" 11 | 12 | class LoginWidget : public FluentWidget 13 | { 14 | Q_OBJECT 15 | public: 16 | explicit LoginWidget(bool autoLogin = false); 17 | 18 | signals: 19 | void loginComplete(int code); 20 | 21 | private slots: 22 | void onBtnLoginClicked(); 23 | 24 | private: 25 | void initUI(); 26 | 27 | LineEdit *m_editUser; 28 | LineEdit *m_editPass; 29 | CheckBox *m_autoLogin; 30 | PrimaryPushButton *m_btnLogin; 31 | 32 | void loading(bool load); 33 | void userLogin(); 34 | }; 35 | 36 | #endif // LOGINWIDGET_H 37 | -------------------------------------------------------------------------------- /libs/include/QFluent/progress/ProgressRing.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ProgressBar.h" 4 | #include "FluentGlobal.h" 5 | 6 | class QFLUENT_EXPORT ProgressRing : public ProgressBar 7 | { 8 | Q_OBJECT 9 | Q_PROPERTY(int strokeWidth READ getStrokeWidth WRITE setStrokeWidth NOTIFY strokeWidthChanged) 10 | 11 | public: 12 | explicit ProgressRing(QWidget *parent = nullptr, bool useAni = true); 13 | ~ProgressRing() override = default; 14 | 15 | int getStrokeWidth() const; 16 | void setStrokeWidth(int w); 17 | 18 | void paintEvent(QPaintEvent *event) override; 19 | 20 | signals: 21 | void strokeWidthChanged(int w); 22 | 23 | private: 24 | QColor lightBackgroundColor; 25 | QColor darkBackgroundColor; 26 | 27 | int _strokeWidth; 28 | 29 | void _drawText(QPainter &painter, const QString &text); 30 | 31 | }; 32 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # C++ objects and libs 2 | *.slo 3 | *.lo 4 | *.o 5 | *.a 6 | *.la 7 | *.lai 8 | *.so 9 | *.so.* 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 | *.qm 32 | *.prl 33 | 34 | # Qt unit tests 35 | target_wrapper.* 36 | 37 | # QtCreator 38 | *.autosave 39 | 40 | # QtCreator Qml 41 | *.qmlproject.user 42 | *.qmlproject.user.* 43 | 44 | # QtCreator CMake 45 | CMakeLists.txt.user* 46 | 47 | # QtCreator 4.8< compilation database 48 | compile_commands.json 49 | 50 | # QtCreator local machine specific files for imported projects 51 | *creator.user* 52 | 53 | *_qmlcache.qrc 54 | 55 | /build 56 | -------------------------------------------------------------------------------- /src/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "MainWindow.h" 3 | 4 | int main(int argc, char *argv[]) 5 | { 6 | #if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) 7 | QGuiApplication::setHighDpiScaleFactorRoundingPolicy( 8 | Qt::HighDpiScaleFactorRoundingPolicy::PassThrough); 9 | #endif 10 | #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) 11 | QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); 12 | QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); 13 | #endif 14 | 15 | QCoreApplication::setAttribute(Qt::AA_DontCreateNativeWidgetSiblings); 16 | 17 | QApplication app(argc, argv); 18 | app.setStyle("Fusion"); 19 | 20 | QFont font; 21 | font.setFamilies({"Microsoft YaHei", "PingFang SC", "Segoe UI"}); 22 | font.setPixelSize(14); 23 | app.setFont(font); 24 | 25 | MainWindow w; 26 | w.show(); 27 | return app.exec(); 28 | } 29 | -------------------------------------------------------------------------------- /libs/include/QFluent/CheckBox.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "FluentGlobal.h" 6 | 7 | class QEnterEvent; 8 | class CheckBoxPrivate; 9 | class QFLUENT_EXPORT CheckBox : public QCheckBox { 10 | Q_OBJECT 11 | Q_DECLARE_PRIVATE_D(d_ptr, CheckBox) 12 | 13 | public: 14 | explicit CheckBox(QWidget *parent = nullptr); 15 | CheckBox(const QString &text, QWidget *parent = nullptr); 16 | ~CheckBox(); 17 | 18 | protected: 19 | void mousePressEvent(QMouseEvent *event) override; 20 | void mouseReleaseEvent(QMouseEvent *event) override; 21 | #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) 22 | void enterEvent(QEnterEvent *event) override; 23 | #else 24 | void enterEvent(QEvent *event) override; 25 | #endif 26 | void leaveEvent(QEvent *event) override; 27 | void paintEvent(QPaintEvent *event) override; 28 | 29 | private: 30 | QScopedPointer d_ptr; 31 | }; 32 | -------------------------------------------------------------------------------- /libs/include/QFluent/menu/MenuActionListWidget.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "FluentGlobal.h" 6 | 7 | class MenuAnimation; 8 | class QFLUENT_EXPORT MenuActionListWidget : public QListWidget { 9 | Q_OBJECT 10 | public: 11 | explicit MenuActionListWidget(QWidget* parent = nullptr); 12 | void setItemHeight(int height); 13 | void setMaxVisibleItems(int num); 14 | int maxVisibleItems() const; 15 | void adjustSize(const QPoint& pos = QPoint(), Fluent::MenuAnimation aniType = Fluent::MenuAnimation::NONE); 16 | int itemHeight() const; 17 | int itemsHeight() const; 18 | 19 | int heightForAnimation(const QPoint& pos, Fluent::MenuAnimation aniType = Fluent::MenuAnimation::NONE); 20 | QPoint availableViewSize(const QPoint& pos, Fluent::MenuAnimation aniType = Fluent::MenuAnimation::NONE); 21 | 22 | protected: 23 | void wheelEvent(QWheelEvent* e) override; 24 | }; 25 | -------------------------------------------------------------------------------- /libs/include/QFluent/FluentWidget.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "FluentGlobal.h" 6 | 7 | class FluentWidgetPrivate; 8 | class QFLUENT_EXPORT FluentWidget : public QMainWindow 9 | { 10 | Q_OBJECT 11 | Q_DECLARE_PRIVATE_D(d_ptr, FluentWidget) 12 | 13 | public: 14 | explicit FluentWidget(QMainWindow *parent = nullptr); 15 | ~FluentWidget(); 16 | 17 | void setWindowButtonHint(Fluent::WindowButtonHint hint, bool isEnable = true); 18 | void setWindowButtonHints(Fluent::WindowButtonHints hints); 19 | Fluent::WindowButtonHints windowButtonHints() const; 20 | 21 | void setWindowEffect(Fluent::WindowEffect effect); 22 | Fluent::WindowEffect windowEffect() const; 23 | 24 | void setCustomWindowIcon(const QPixmap &pixmap, const QSize &size); 25 | 26 | protected: 27 | bool event(QEvent *event) override; 28 | 29 | private: 30 | QScopedPointer d_ptr; 31 | 32 | }; 33 | -------------------------------------------------------------------------------- /libs/include/QFluent/settings/OptionsSettingCard.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ExpandSettingCard.h" 4 | 5 | class RadioButton; 6 | class QAbstractButton; 7 | class QFLUENT_EXPORT OptionsSettingCard : public ExpandSettingCard { 8 | Q_OBJECT 9 | 10 | public: 11 | OptionsSettingCard(const QIcon& icon, 12 | const QString& title, 13 | const QString& content = QString(), 14 | const QVector& texts = QVector(), 15 | QWidget* parent = nullptr); 16 | 17 | void setValue(const QVariant& value); 18 | 19 | signals: 20 | void optionChanged(int index, const QString& text); 21 | 22 | private slots: 23 | void onButtonClicked(QAbstractButton *button); 24 | 25 | private: 26 | QVector texts; 27 | QString configName; 28 | QLabel* choiceLabel; 29 | QButtonGroup* buttonGroup; 30 | 31 | void adjustViewSize(); 32 | }; 33 | -------------------------------------------------------------------------------- /libs/include/QFluent/menu/SubMenuItemWidget.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | class QMenu; 6 | class RoundMenu; 7 | class QEnterEvent; 8 | class QPaintEvent; 9 | class QListWidgetItem; 10 | class SubMenuItemWidget : public QWidget 11 | { 12 | Q_OBJECT 13 | 14 | public: 15 | explicit SubMenuItemWidget(QMenu* menu, QListWidgetItem* item, QWidget* parent = nullptr); 16 | explicit SubMenuItemWidget(RoundMenu* menu, QListWidgetItem* item, QWidget* parent = nullptr); 17 | 18 | signals: 19 | void showMenuSig(QListWidgetItem* item); 20 | 21 | protected: 22 | #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) 23 | void enterEvent(QEnterEvent* event) override; 24 | #else 25 | void enterEvent(QEvent* event) override; 26 | #endif 27 | void paintEvent(QPaintEvent* event) override; 28 | 29 | private: 30 | QMenu* menuAsQMenu = nullptr; 31 | RoundMenu* menuAsRoundMenu = nullptr; 32 | QListWidgetItem* item = nullptr; 33 | }; 34 | -------------------------------------------------------------------------------- /res/style/dark/gallery_interface.qss: -------------------------------------------------------------------------------- 1 | GalleryInterface, 2 | ToolBar, 3 | #view { 4 | background-color: transparent; 5 | } 6 | 7 | QScrollArea { 8 | border: none; 9 | } 10 | 11 | 12 | ToolBar>CaptionLabel { 13 | color: white; 14 | } 15 | 16 | ExampleCard { 17 | background-color: transparent; 18 | color: white; 19 | } 20 | 21 | TitleLabel, 22 | StrongBodyLabel { 23 | color: white; 24 | } 25 | 26 | ExampleCard>#card { 27 | border: 1px solid rgb(36, 36, 36); 28 | border-radius: 10px; 29 | background-color: rgba(0, 0, 0, 0.1795); 30 | } 31 | 32 | ExampleCard>#card QLabel { 33 | font: 14px 'Segoe UI', 'Microsoft YaHei', 'PingFang SC'; 34 | color: white; 35 | } 36 | 37 | ExampleCard>#card InfoBadge { 38 | font-size: 11px; 39 | } 40 | 41 | 42 | #sourceWidget { 43 | background-color: rgba(255, 255, 255, 0.09); 44 | border-top: 1px solid rgb(36, 36, 36); 45 | border-bottom-left-radius: 10px; 46 | border-bottom-right-radius: 10px; 47 | } 48 | -------------------------------------------------------------------------------- /res/style/light/gallery_interface.qss: -------------------------------------------------------------------------------- 1 | GalleryInterface, ToolBar, #view { 2 | background-color: transparent; 3 | } 4 | 5 | QScrollArea { 6 | border: none; 7 | } 8 | 9 | ToolBar > StrongBodyLabel { 10 | color: black; 11 | } 12 | 13 | ToolBar > CaptionLabel { 14 | color: rgb(95, 95, 95); 15 | } 16 | 17 | ExampleCard { 18 | background-color: transparent; 19 | } 20 | 21 | TitleLabel, 22 | StrongBodyLabel { 23 | color: black; 24 | } 25 | 26 | ExampleCard > #card { 27 | border: 1px solid rgba(0, 0, 0, 0.05); 28 | border-radius: 10px; 29 | background-color: rgba(0, 0, 0, 0.024); 30 | } 31 | 32 | ExampleCard > #card QLabel { 33 | font: 14px 'Segoe UI', 'Microsoft YaHei', 'PingFang SC'; 34 | color: black; 35 | } 36 | 37 | ExampleCard> #card InfoBadge { 38 | font-size: 11px; 39 | } 40 | 41 | #sourceWidget { 42 | background-color: rgba(255, 255, 255, 0.667); 43 | border-top: 1px solid rgba(0, 0, 0, 0.05); 44 | border-bottom-left-radius: 10px; 45 | border-bottom-right-radius: 10px; 46 | } 47 | -------------------------------------------------------------------------------- /src/DateTimeInputInterface.cpp: -------------------------------------------------------------------------------- 1 | #include "DateTimeInputInterface.h" 2 | #include 3 | #include "QFluent/date_time/DatePicker.h" 4 | #include "QFluent/date_time/TimePicker.h" 5 | #include "QFluent/date_time/CalendarPicker.h" 6 | 7 | DateTimeInputInterface::DateTimeInputInterface(QWidget *parent) 8 | : GalleryInterface("日期和时间", "", parent) 9 | { 10 | setObjectName("DateTimeInputInterface"); 11 | 12 | auto calendar = new CalendarPicker(this); 13 | connect(calendar, &CalendarPicker::dateChanged, this, [](const QDate &date){ 14 | qDebug() << date; 15 | }); 16 | addExampleCard("日历选择器", calendar); 17 | addExampleCard("日期选择器", new ZhDatePicker(this)); 18 | addExampleCard("时间选择器", new AMTimePicker(this)); 19 | 20 | addExampleCard("24小时制的时间选择器", new TimePicker(this, false)); 21 | 22 | auto timePicker = new TimePicker(this, true); 23 | connect(timePicker, &TimePicker::timeChanged, this, [](const QTime &time){ 24 | qDebug() << time; 25 | }); 26 | addExampleCard("显示秒的时间选择器", timePicker); 27 | } 28 | -------------------------------------------------------------------------------- /libs/include/QFluent/RadioButton.h: -------------------------------------------------------------------------------- 1 | #ifndef RADIOBUTTON_H 2 | #define RADIOBUTTON_H 3 | 4 | #include 5 | 6 | #include "FluentGlobal.h" 7 | 8 | class QFLUENT_EXPORT RadioButton : public QRadioButton 9 | { 10 | Q_OBJECT 11 | 12 | public: 13 | explicit RadioButton(QWidget *parent = nullptr); 14 | explicit RadioButton(const QString &text, QWidget *parent = nullptr); 15 | 16 | protected: 17 | void paintEvent(QPaintEvent *event) override; 18 | #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) 19 | void enterEvent(QEnterEvent *event) override; 20 | #else 21 | void enterEvent(QEvent *event) override; 22 | #endif 23 | void leaveEvent(QEvent *event) override; 24 | 25 | private: 26 | void init(); 27 | void drawIndicator(QPainter &painter); 28 | void drawText(QPainter &painter); 29 | void drawCircle(QPainter &painter, const QPoint ¢er, int radius, int thickness, const QColor &borderColor, const QColor &filledColor); 30 | 31 | QPoint indicatorPos_; 32 | bool isHover_; 33 | }; 34 | 35 | #endif // RADIOBUTTON_H 36 | -------------------------------------------------------------------------------- /libs/include/QFluent/CardWidget.h: -------------------------------------------------------------------------------- 1 | #ifndef CARDWIDGET_H 2 | #define CARDWIDGET_H 3 | 4 | #include "Animation.h" 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #include "FluentGlobal.h" 12 | 13 | class QFLUENT_EXPORT CardWidget : public BackgroundAnimationWidget 14 | { 15 | Q_OBJECT 16 | Q_PROPERTY(int borderRadius READ getBorderRadius WRITE setBorderRadius) 17 | 18 | public: 19 | explicit CardWidget(QWidget *parent = nullptr); 20 | 21 | void setClickEnabled(bool isEnabled); 22 | bool isClickEnabled() const; 23 | 24 | int getBorderRadius() const; 25 | void setBorderRadius(int radius); 26 | 27 | signals: 28 | void clicked(); 29 | 30 | protected: 31 | void mouseReleaseEvent(QMouseEvent *e) override; 32 | void paintEvent(QPaintEvent *e) override; 33 | 34 | private: 35 | QColor _normalBackgroundColor() const; 36 | QColor _hoverBackgroundColor() const; 37 | QColor _pressedBackgroundColor() const; 38 | 39 | bool _isClickEnabled; 40 | int _borderRadius; 41 | }; 42 | 43 | #endif // CARDWIDGET_H 44 | -------------------------------------------------------------------------------- /libs/include/QFluent/scrollbar/SmoothScroll.h: -------------------------------------------------------------------------------- 1 | #ifndef SMOOTH_SCROLL_H 2 | #define SMOOTH_SCROLL_H 3 | 4 | #include 5 | #include 6 | 7 | #include "FluentGlobal.h" 8 | 9 | class QTimer; 10 | class QWheelEvent; 11 | class QAbstractScrollArea; 12 | class QFLUENT_EXPORT SmoothScroll : public QObject { 13 | Q_OBJECT 14 | public: 15 | SmoothScroll(QAbstractScrollArea* widget, Qt::Orientation orient = Qt::Vertical); 16 | void setSmoothMode(Fluent::SmoothMode smoothMode); 17 | void wheelEvent(QWheelEvent* e); 18 | 19 | private slots: 20 | void smoothMove(); 21 | 22 | private: 23 | qreal subDelta(qreal delta, int stepsLeft); 24 | 25 | QAbstractScrollArea* widget; 26 | Qt::Orientation orient; 27 | int fps = 60; 28 | int duration = 400; 29 | int stepsTotal = 0; 30 | qreal stepRatio = 1.5; 31 | qreal acceleration = 1; 32 | QWheelEvent* lastWheelEvent = nullptr; 33 | std::deque scrollStamps; 34 | std::deque> stepsLeftQueue; 35 | QTimer* smoothMoveTimer; 36 | Fluent::SmoothMode smoothMode = Fluent::SmoothMode::LINEAR; 37 | }; 38 | 39 | #endif // SMOOTH_SCROLL_H 40 | -------------------------------------------------------------------------------- /libs/include/QFluent/layout/ExpandLayout.h: -------------------------------------------------------------------------------- 1 | #ifndef EXPANDLAYOUT_H 2 | #define EXPANDLAYOUT_H 3 | 4 | #include 5 | #include "FluentGlobal.h" 6 | 7 | class QFLUENT_EXPORT ExpandLayout : public QLayout 8 | { 9 | Q_OBJECT 10 | 11 | public: 12 | explicit ExpandLayout(QWidget *parent = nullptr); 13 | ~ExpandLayout(); 14 | 15 | void addWidget(QWidget *widget); 16 | void addItem(QLayoutItem *item) override; 17 | int count() const override; 18 | QLayoutItem *itemAt(int index) const override; 19 | QLayoutItem *takeAt(int index) override; 20 | 21 | Qt::Orientations expandingDirections() const override; 22 | bool hasHeightForWidth() const override; 23 | int heightForWidth(int width) const override; 24 | 25 | void setGeometry(const QRect &rect) override; 26 | QSize sizeHint() const override; 27 | QSize minimumSize() const override; 28 | 29 | protected: 30 | bool eventFilter(QObject *obj, QEvent *event) override; 31 | 32 | private: 33 | int doLayout(const QRect &rect, bool move) const; 34 | mutable QList m_items; 35 | mutable QList m_widgets; // 用于快速访问和事件过滤 36 | }; 37 | 38 | #endif // EXPANDLAYOUT_H 39 | -------------------------------------------------------------------------------- /libs/include/QFluent/IconWidget.h: -------------------------------------------------------------------------------- 1 | #ifndef ICONWIDGET_H 2 | #define ICONWIDGET_H 3 | 4 | #include 5 | 6 | #include "FluentGlobal.h" 7 | #include "FluentIcon.h" 8 | 9 | class QIcon; 10 | class IconWidgetPrivate; 11 | class QFLUENT_EXPORT IconWidget : public QWidget 12 | { 13 | Q_OBJECT 14 | Q_DECLARE_PRIVATE_D(d_ptr, IconWidget) 15 | 16 | public: 17 | explicit IconWidget(QWidget *parent = nullptr); 18 | explicit IconWidget(const QIcon &icon, QWidget *parent = nullptr); 19 | explicit IconWidget(const QString &iconPath, QWidget *parent = nullptr); 20 | explicit IconWidget(const FluentIconBase &icon, QWidget* parent = nullptr); 21 | ~IconWidget(); 22 | 23 | void setIcon(const QIcon &icon); 24 | void setIcon(const QString &iconPath); 25 | void setFluentIcon(const FluentIconBase &icon); 26 | QIcon getIcon() const; 27 | 28 | void setIconTheme(Fluent::ThemeMode theme); 29 | Fluent::ThemeMode getIconTheme(); 30 | 31 | QSize sizeHint() const override; 32 | 33 | protected: 34 | void paintEvent(QPaintEvent *event) override; 35 | 36 | private: 37 | QScopedPointer d_ptr; 38 | 39 | }; 40 | 41 | #endif // ICONWIDGET_H 42 | -------------------------------------------------------------------------------- /src/HomeInterface.h: -------------------------------------------------------------------------------- 1 | // home_interface.h 2 | #ifndef HOME_INTERFACE_H 3 | #define HOME_INTERFACE_H 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #include "QFluent/ScrollArea.h" 15 | 16 | class LinkCardView; 17 | class SampleCardView; 18 | 19 | class BannerWidget : public QWidget 20 | { 21 | Q_OBJECT 22 | 23 | public: 24 | explicit BannerWidget(QWidget *parent = nullptr); 25 | 26 | protected: 27 | void paintEvent(QPaintEvent *event) override; 28 | 29 | private: 30 | QVBoxLayout *m_vBoxLayout; 31 | QLabel *m_galleryLabel; 32 | QPixmap m_banner; 33 | LinkCardView *m_linkCardView; 34 | 35 | void setupUI(); 36 | void setupLinks(); 37 | }; 38 | 39 | class HomeInterface : public ScrollArea 40 | { 41 | Q_OBJECT 42 | 43 | public: 44 | explicit HomeInterface(QWidget *parent = nullptr); 45 | 46 | private: 47 | BannerWidget *m_banner; 48 | QWidget *m_view; 49 | QVBoxLayout *m_vBoxLayout; 50 | 51 | void initWidget(); 52 | void loadSamples(); 53 | }; 54 | 55 | #endif // HOME_INTERFACE_H 56 | -------------------------------------------------------------------------------- /libs/include/Theme.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "FluentGlobal.h" 9 | 10 | class ThemePrivate; 11 | class QFLUENT_EXPORT Theme : public QObject 12 | { 13 | Q_OBJECT 14 | Q_DECLARE_PRIVATE_D(d_ptr, Theme) 15 | 16 | public: 17 | explicit Theme(QObject* parent = nullptr); 18 | ~Theme() override; 19 | static Theme *instance(); 20 | 21 | Fluent::ThemeMode theme() const; 22 | void setTheme(Fluent::ThemeMode theme, bool save = false, bool lazy = false); 23 | void toggleTheme(bool save = false, bool lazy = false); 24 | 25 | // 颜色管理 26 | QColor themeColor() const; 27 | QColor themeColor(Fluent::ThemeColor type) const; 28 | void setThemeColor(const QColor& color, bool save = false, bool lazy = false); 29 | 30 | bool isDarkTheme() const; 31 | 32 | 33 | void setFont(QWidget *widget, int fontSize = 14, QFont::Weight weight = QFont::Normal); 34 | QFont getFont(int fontSize = 14, QFont::Weight weight = QFont::Normal); 35 | 36 | Q_SIGNALS: 37 | Q_SIGNAL void themeModeChanged(Fluent::ThemeMode themeType); 38 | 39 | private: 40 | QScopedPointer d_ptr; 41 | }; 42 | -------------------------------------------------------------------------------- /libs/include/QFluent/date_time/CalendarPicker.h: -------------------------------------------------------------------------------- 1 | #ifndef CALENDARPICKER_H 2 | #define CALENDARPICKER_H 3 | 4 | #include 5 | 6 | #include "FluentGlobal.h" 7 | #include "CalendarView.h" 8 | 9 | using FIF = Fluent::IconType; 10 | 11 | 12 | class QFLUENT_EXPORT CalendarPicker : public QPushButton 13 | { 14 | Q_OBJECT 15 | Q_PROPERTY(QDate date READ getDate WRITE setDate) 16 | Q_PROPERTY(QString dateFormat READ getDateFormat WRITE setDateFormat) 17 | 18 | public: 19 | explicit CalendarPicker(QWidget* parent = nullptr); 20 | ~CalendarPicker() = default; 21 | 22 | QDate getDate() const; 23 | void setDate(const QDate& date); 24 | 25 | void reset(); 26 | QString getDateFormat() const; 27 | void setDateFormat(QString format); 28 | bool isResetEnabled() const; 29 | void setResetEnabled(bool isEnabled); 30 | 31 | signals: 32 | void dateChanged(const QDate& date); 33 | 34 | protected: 35 | void paintEvent(QPaintEvent* e) override; 36 | 37 | private slots: 38 | void _showCalendarView(); 39 | void _onDateChanged(const QDate& date); 40 | 41 | private: 42 | QDate _date; 43 | QString _dateFormat; 44 | bool _isResetEnabled; 45 | }; 46 | 47 | #endif // CALENDARPICKER_H 48 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # QFluentKit 2 | 3 | **QFluentKit** 是一个基于 Qt Widgets 的 Fluent Design 风格 UI 组件库,致力于为 Qt C++ 开发者提供现代化、美观且易用的界面解决方案。 4 | 5 | ## 🌟 特性亮点 6 | 7 | - **Fluent Design 风格**:遵循微软 Fluent Design 设计语言,带来现代、一致的视觉体验。 8 | - **无边框窗口支持**:集成 QWindowKit 实现优雅的无边框窗口管理(包括拖拽、缩放、阴影等)。 9 | - **跨版本兼容**:动态库支持 **Qt 5.15+** 和 **Qt 6**(兼容 MinGW 与 MSVC 编译器)。 10 | - **开箱即用**:本项目展示了如何在实际应用中集成和使用 QFluentKit 动态库。 11 | 12 | ## 📸 示例截图 13 | 14 | 15 | 16 | 17 | 18 | 19 | ## 🛠️ 构建环境 20 | 21 | - **操作系统**:Windows 10 或更高版本 22 | - **Qt 版本**:≥ 5.15 23 | - **主分支构建配置**: 24 | - Qt 6.8.3 / Qt 5.15.2 25 | - MSVC 2022 64-bit 26 | 27 | > 💡 主分支可在 Qt 6.8.3 + MSVC 或 Qt 5.15.2 + MSVC 环境下直接构建并运行。QFluentKit 动态库本身兼容 Qt 5.15 及 Qt 6 的多个版本,并支持 MinGW 与 MSVC 编译器;但本仓库的示例程序仅预置了上述两种 MSVC 环境(Qt 6.8.3 / Qt 5.15.2)构建的动态库。 28 | 29 | ## 📦 依赖与参考 30 | 31 | - 核心窗口管理:[QWindowKit](https://github.com/stdware/qwindowkit) 32 | - 设计灵感来源:[PyQt-Fluent-Widgets](https://github.com/zhiyiYo/PyQt-Fluent-Widgets) 33 | 34 | ## 📺 在线演示 35 | 36 | 想先看看效果?欢迎观看 [Bilibili 演示视频](https://www.bilibili.com/video/BV1p211BmEpa/)! 37 | 38 | ## 📄 许可证 39 | 40 | - 本项目采用**自定义免费使用许可**。 41 | - 免费供个人和商业项目使用。 42 | - 基于 Qt 开源版(LGPL)开发。 43 | - 保留版权、禁止反编译、免责。 44 | - 完整许可条款请参阅项目根目录下的 `LICENSE` 文件。 -------------------------------------------------------------------------------- /res/style/dark/icon_interface.qss: -------------------------------------------------------------------------------- 1 | IconCard { 2 | background-color: rgb(43, 43, 43); 3 | border: 1px solid rgb(29, 29, 29); 4 | border-radius: 6px; 5 | } 6 | 7 | IconCard > QLabel { 8 | color: rgb(207, 207, 207); 9 | font: 11px 'Segoe UI', 'PingFang SC'; 10 | } 11 | 12 | IconCard[isSelected=true] { 13 | background-color: --ThemeColorPrimary; 14 | } 15 | 16 | IconCard[isSelected=true] > QLabel { 17 | color: black; 18 | } 19 | 20 | #scrollWidget, #iconView { 21 | background-color: rgb(32, 32, 32); 22 | } 23 | 24 | IconCardView { 25 | background-color: transparent; 26 | } 27 | 28 | #iconView { 29 | border: 1px solid rgb(36, 36, 36); 30 | border-radius: 10px; 31 | } 32 | 33 | IconInfoPanel { 34 | background-color: rgb(43, 43, 43); 35 | border-left: 1px solid rgb(29, 29, 29); 36 | border-top-right-radius: 10px; 37 | border-bottom-right-radius: 10px; 38 | } 39 | 40 | IconInfoPanel>#nameLabel { 41 | font: 15px 'Segoe UI', 'PingFang SC'; 42 | font-weight: bold; 43 | color: white; 44 | } 45 | 46 | IconInfoPanel>#subTitleLabel { 47 | font: 14px 'Segoe UI', 'Microsoft YaHei', 'PingFang SC'; 48 | color: white; 49 | } 50 | 51 | IconInfoPanel>QLabel { 52 | font: 12px 'Segoe UI', 'PingFang SC'; 53 | color: rgb(207, 207, 207); 54 | } 55 | 56 | -------------------------------------------------------------------------------- /res/style/light/icon_interface.qss: -------------------------------------------------------------------------------- 1 | IconCard { 2 | background-color: rgb(251, 251, 251); 3 | border: 1px solid rgb(229, 229, 229); 4 | border-radius: 6px; 5 | } 6 | 7 | IconCard > QLabel { 8 | color: rgb(96, 96, 96); 9 | font: 11px 'Segoe UI', 'PingFang SC'; 10 | } 11 | 12 | IconCard[isSelected=true] { 13 | background-color: --ThemeColorPrimary; 14 | } 15 | 16 | IconCard[isSelected=true] > QLabel { 17 | color: white; 18 | } 19 | 20 | #scrollWidget, #iconView { 21 | background-color: rgb(243, 243, 243); 22 | } 23 | 24 | IconCardView { 25 | background-color: transparent; 26 | } 27 | 28 | #iconView { 29 | border: 1px solid rgb(234, 234, 234); 30 | border-radius: 10px; 31 | } 32 | 33 | 34 | IconInfoPanel { 35 | background-color: rgb(251, 251, 251); 36 | border-left: 1px solid rgb(229, 229, 229); 37 | border-top-right-radius: 10px; 38 | border-bottom-right-radius: 10px; 39 | } 40 | 41 | 42 | IconInfoPanel > #nameLabel { 43 | font: 15px 'Segoe UI', 'PingFang SC'; 44 | font-weight: bold; 45 | color: black; 46 | } 47 | 48 | IconInfoPanel > #subTitleLabel { 49 | font: 14px 'Segoe UI', 'Microsoft YaHei', 'PingFang SC'; 50 | color: black; 51 | } 52 | 53 | IconInfoPanel > QLabel { 54 | font: 12px 'Segoe UI', 'PingFang SC'; 55 | color: rgb(96, 96, 96); 56 | } 57 | 58 | -------------------------------------------------------------------------------- /res/icons/Text_black.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /res/icons/Text_white.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/LayoutInterface.cpp: -------------------------------------------------------------------------------- 1 | #include "LayoutInterface.h" 2 | 3 | #include 4 | 5 | #include "QFluent/PushButton.h" 6 | #include "QFluent/layout/FlowLayout.h" 7 | 8 | LayoutInterface::LayoutInterface(QWidget *parent) 9 | : GalleryInterface("布局", "", parent) 10 | { 11 | setObjectName("LayoutInterface"); 12 | 13 | addExampleCard("不带动画效果的流式布局", createWidget(false), "", 1); 14 | addExampleCard("带动画效果的流式布局", createWidget(true), "", 1); 15 | } 16 | 17 | 18 | QWidget *LayoutInterface::createWidget(bool animation) 19 | { 20 | QStringList texts; 21 | texts << "随便点点" 22 | << "点到为止" 23 | << "手滑勿怪" 24 | << "假装很忙" 25 | << "正在摸鱼" 26 | << "别信这个" 27 | << "纯属虚构" 28 | << "演示专用" 29 | << "点完就跑" 30 | << "无效操作" 31 | << "仅供观赏" 32 | << "点击无效" 33 | << "看看就好" 34 | << "莫当真啊" 35 | << "稍后上线" 36 | << "假装成功" 37 | << "快点我呀" 38 | << "其实没用"; 39 | auto widget = new QWidget(); 40 | auto layout = new FlowLayout(widget, animation); 41 | 42 | layout->setContentsMargins(0, 0, 0, 0); 43 | layout->setVerticalSpacing(20); 44 | layout->setHorizontalSpacing(10); 45 | 46 | foreach (const QString &text, texts) { 47 | layout->addWidget(new PushButton(text, widget)); 48 | } 49 | return widget; 50 | } 51 | -------------------------------------------------------------------------------- /src/Card/LinkCard.h: -------------------------------------------------------------------------------- 1 | #ifndef LINK_CARD_H 2 | #define LINK_CARD_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #include "QFluent/ScrollArea.h" 15 | 16 | class IconWidget; 17 | class FluentIcon; 18 | 19 | class LinkCard : public QFrame 20 | { 21 | Q_OBJECT 22 | 23 | public: 24 | LinkCard(const QIcon &icon, const QString &title, const QString &content, 25 | const QString &url, QWidget *parent = nullptr); 26 | 27 | protected: 28 | void mouseReleaseEvent(QMouseEvent *event) override; 29 | 30 | private: 31 | QUrl m_url; 32 | IconWidget *m_iconWidget; 33 | QLabel *m_titleLabel; 34 | QLabel *m_contentLabel; 35 | IconWidget *m_urlWidget; 36 | 37 | void initWidget(); 38 | }; 39 | 40 | class LinkCardView : public ScrollArea 41 | { 42 | Q_OBJECT 43 | 44 | public: 45 | explicit LinkCardView(QWidget *parent = nullptr); 46 | 47 | void addCard(const QIcon &icon, const QString &title, const QString &content, const QString &url); 48 | void addCard(const QString &iconPath, const QString &title, const QString &content, const QString &url); 49 | 50 | private: 51 | QWidget *m_view; 52 | QHBoxLayout *m_hBoxLayout; 53 | 54 | void initWidget(); 55 | }; 56 | 57 | #endif // LINK_CARD_H 58 | -------------------------------------------------------------------------------- /res/icons/Grid_black.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /res/icons/Grid_white.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /libs/include/QFluent/dialog/MaskDialogBase.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "FluentGlobal.h" 6 | 7 | class QEvent; 8 | class QColor; 9 | class QWidget; 10 | class QResizeEvent; 11 | class QHBoxLayout; 12 | class MaskDialogBasePrivate; 13 | class QFLUENT_EXPORT MaskDialogBase : public QDialog 14 | { 15 | Q_OBJECT 16 | Q_DECLARE_PRIVATE_D(d_ptr, MaskDialogBase) 17 | 18 | public: 19 | explicit MaskDialogBase(QWidget* parent = nullptr); 20 | ~MaskDialogBase(); 21 | 22 | QHBoxLayout* hBoxLayout(); 23 | // 获取中心 widget,用于添加内容 24 | QWidget* centerWidget() const; 25 | 26 | // 设置遮罩颜色 27 | void setMaskColor(const QColor& color); 28 | 29 | // 设置阴影效果 30 | void setShadowEffect(int blurRadius = 60, const QPoint& offset = QPoint(0, 10), const QColor& color = QColor(0, 0, 0, 100)); 31 | 32 | // 重写 showEvent 实现淡入动画 33 | void showEvent(QShowEvent* event) override; 34 | 35 | // 重写 done 实现淡出动画 36 | void done(int code) override; 37 | 38 | // 重写 resizeEvent 同步遮罩大小 39 | void resizeEvent(QResizeEvent* event) override; 40 | 41 | void setIsClosableOnMaskClicked(bool enable); 42 | 43 | bool getIsClosableOnMaskClicked(); 44 | 45 | protected: 46 | explicit MaskDialogBase(MaskDialogBasePrivate& dd, QWidget* parent = nullptr); 47 | void onDone(int code); 48 | // 事件过滤器:处理父窗口 resize 和遮罩点击 49 | bool eventFilter(QObject* obj, QEvent* event) override; 50 | 51 | QScopedPointer d_ptr; 52 | 53 | }; 54 | -------------------------------------------------------------------------------- /src/WindowInterface.cpp: -------------------------------------------------------------------------------- 1 | #include "WindowInterface.h" 2 | 3 | #include "QFluent/PushButton.h" 4 | #include "Window/LoginWindow.h" 5 | #include "Window/NavbarWindow.h" 6 | #include "Window/SplitWindow.h" 7 | 8 | #include "MainWindow.h" 9 | #include "ConfigManager.h" 10 | 11 | WindowInterface::WindowInterface(QWidget *parent) 12 | : GalleryInterface("窗口", "", parent) 13 | { 14 | setObjectName("WindowInterface"); 15 | 16 | auto mainWindow = qobject_cast(this->window()); 17 | 18 | auto button1 = new PushButton("弹出窗口", this); 19 | connect(button1, &PushButton::clicked, this, [=](){ 20 | auto loginWindow = new LoginWidget(false); 21 | loginWindow->setWindowModality(Qt::ApplicationModal); 22 | loginWindow->setWindowEffect(mainWindow->windowEffect()); 23 | loginWindow->show(); 24 | }); 25 | addExampleCard("登录窗口", button1); 26 | 27 | auto button2 = new PushButton("弹出窗口", this); 28 | connect(button2, &PushButton::clicked, this, [=](){ 29 | auto navWidget = new NavbarWidget(); 30 | navWidget->setWindowEffect(mainWindow->windowEffect()); 31 | navWidget->show(); 32 | }); 33 | addExampleCard("带导航栏的窗口", button2); 34 | 35 | auto button3 = new PushButton("弹出窗口", this); 36 | connect(button3, &PushButton::clicked, this, [=](){ 37 | auto splitWindow = new SplitWidget(); 38 | splitWindow->setWindowEffect(mainWindow->windowEffect()); 39 | splitWindow->show(); 40 | }); 41 | addExampleCard("分割风格的窗口", button3); 42 | } 43 | 44 | 45 | -------------------------------------------------------------------------------- /libs/include/QFluent/FluentSplitWindow.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "FluentGlobal.h" 6 | #include "FluentIcon.h" 7 | 8 | class NavigationPanel; 9 | class FluentSplitWindowPrivate; 10 | class NavigationAvatarWidget; 11 | class QFLUENT_EXPORT FluentSplitWindow : public QMainWindow 12 | { 13 | Q_OBJECT 14 | Q_DECLARE_PRIVATE_D(d_ptr, FluentSplitWindow) 15 | 16 | public: 17 | FluentSplitWindow(QMainWindow *parent = nullptr); 18 | ~FluentSplitWindow(); 19 | 20 | void setWindowButtonHint(Fluent::WindowButtonHint hint, bool isEnable = true); 21 | void setWindowButtonHints(Fluent::WindowButtonHints hints); 22 | Fluent::WindowButtonHints windowButtonHints() const; 23 | 24 | void setWindowEffect(Fluent::WindowEffect effect); 25 | Fluent::WindowEffect windowEffect() const; 26 | 27 | void setCustomWindowIcon(const QPixmap &pixmap, const QSize &size); 28 | 29 | void addSubInterface(const QString& routeKey, const FluentIconBase& icon, const QString& text, 30 | QWidget* widget, bool selectable = true, 31 | Fluent::NavigationItemPosition position = Fluent::NavigationItemPosition::TOP, 32 | const QString& tooltip = QString(), const QString& parentRouteKey = QString()); 33 | 34 | NavigationPanel *navigationInterface() const; 35 | 36 | 37 | protected: 38 | bool event(QEvent *event) override; 39 | void resizeEvent(QResizeEvent *e) override; 40 | 41 | private: 42 | QScopedPointer d_ptr; 43 | 44 | }; 45 | -------------------------------------------------------------------------------- /libs/include/QFluent/progress/ProgressBar.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include "FluentGlobal.h" 6 | 7 | class QFLUENT_EXPORT ProgressBar : public QProgressBar 8 | { 9 | Q_OBJECT 10 | Q_PROPERTY(bool useAni READ isUseAni WRITE setUseAni NOTIFY useAniChanged) 11 | Q_PROPERTY(float val READ getVal WRITE setVal NOTIFY valChanged) 12 | 13 | public: 14 | explicit ProgressBar(QWidget *parent = nullptr, bool useAni = true); 15 | ~ProgressBar() override = default; 16 | 17 | bool isUseAni() const; 18 | void setUseAni(bool isUse); 19 | float getVal() const; 20 | void setVal(float v); 21 | 22 | void resume(); 23 | void pause(); 24 | void setPaused(bool isPaused); 25 | bool isPaused() const; 26 | void error(); 27 | void setError(bool isError); 28 | bool isError() const; 29 | 30 | void setCustomBarColor(const QColor &light, const QColor &dark); 31 | void setCustomBackgroundColor(const QColor &light, const QColor &dark); 32 | 33 | QColor barColor() const; 34 | 35 | signals: 36 | void useAniChanged(bool isUse); 37 | void valChanged(float val); 38 | 39 | protected: 40 | void paintEvent(QPaintEvent *event) override; 41 | 42 | private slots: 43 | void _onValueChanged(int value); 44 | 45 | private: 46 | float _val; 47 | bool _useAni; 48 | QColor lightBackgroundColor; 49 | QColor darkBackgroundColor; 50 | QColor _lightBarColor; 51 | QColor _darkBarColor; 52 | QPropertyAnimation ani; 53 | bool _isPaused; 54 | bool _isError; 55 | }; 56 | -------------------------------------------------------------------------------- /libs/include/QFluent/FluentWindow.h: -------------------------------------------------------------------------------- 1 | #ifndef FLUENTWINDOW_H 2 | #define FLUENTWINDOW_H 3 | 4 | #include 5 | 6 | #include "FluentGlobal.h" 7 | #include "FluentIcon.h" 8 | 9 | class StackedWidget; 10 | class NavigationPanel; 11 | class FluentWindowPrivate; 12 | class NavigationAvatarWidget; 13 | class QFLUENT_EXPORT FluentWindow : public QMainWindow 14 | { 15 | Q_OBJECT 16 | Q_DECLARE_PRIVATE_D(d_ptr, FluentWindow) 17 | 18 | public: 19 | FluentWindow(QMainWindow *parent = nullptr); 20 | ~FluentWindow(); 21 | 22 | void setWindowButtonHint(Fluent::WindowButtonHint hint, bool isEnable = true); 23 | void setWindowButtonHints(Fluent::WindowButtonHints hints); 24 | Fluent::WindowButtonHints windowButtonHints() const; 25 | 26 | void setWindowEffect(Fluent::WindowEffect effect); 27 | Fluent::WindowEffect windowEffect() const; 28 | 29 | void setCustomWindowIcon(const QPixmap &pixmap, const QSize &size); 30 | 31 | void addSubInterface(const QString& routeKey, const FluentIconBase& icon, const QString& text, 32 | QWidget* widget, bool selectable = true, 33 | Fluent::NavigationItemPosition position = Fluent::NavigationItemPosition::TOP, 34 | const QString& tooltip = QString(), const QString& parentRouteKey = QString()); 35 | 36 | NavigationPanel *navigationInterface() const; 37 | StackedWidget *stackedWidget() const; 38 | 39 | Q_SIGNALS: 40 | void backRequested(); 41 | 42 | protected: 43 | bool event(QEvent *event) override; 44 | 45 | private: 46 | QScopedPointer d_ptr; 47 | 48 | }; 49 | #endif // FLUENTWINDOW_H 50 | -------------------------------------------------------------------------------- /libs/include/QFluent/FluentTitleBar.h: -------------------------------------------------------------------------------- 1 | #ifndef FLUENTTITLEBAR_H 2 | #define FLUENTTITLEBAR_H 3 | 4 | #include 5 | #include 6 | #include "FluentGlobal.h" 7 | 8 | class QEvent; 9 | class QLabel; 10 | class QWidget; 11 | class FluentTitleBarPrivate; 12 | class QFLUENT_EXPORT FluentTitleBar : public QFrame { 13 | Q_OBJECT 14 | Q_DECLARE_PRIVATE_D(d_ptr, FluentTitleBar) 15 | 16 | public: 17 | explicit FluentTitleBar(QWidget *parent = nullptr); 18 | ~FluentTitleBar(); 19 | 20 | public: 21 | QLabel *titleLabel() const; 22 | QAbstractButton *iconButton() const; 23 | QAbstractButton *themeButton() const; 24 | QAbstractButton *minButton() const; 25 | QAbstractButton *maxButton() const; 26 | QAbstractButton *closeButton() const; 27 | QAbstractButton *backButton() const; 28 | QLabel *iconLabel() const; 29 | 30 | QWidget *hostWidget() const; 31 | void setHostWidget(QWidget *w); 32 | void setWindowButtonHint(Fluent::WindowButtonHint hint, bool isEnable = true); 33 | void setWindowButtonHints(Fluent::WindowButtonHints hints); 34 | Fluent::WindowButtonHints windowButtonHints() const; 35 | 36 | Q_SIGNALS: 37 | void backRequested(); 38 | void themeRequested(bool dark = true); 39 | void minimizeRequested(); 40 | void maximizeRequested(bool max = false); 41 | void closeRequested(); 42 | 43 | protected: 44 | bool eventFilter(QObject *obj, QEvent *event) override; 45 | 46 | virtual void titleChanged(const QString &text); 47 | virtual void iconChanged(const QIcon &icon); 48 | 49 | private: 50 | QScopedPointer d_ptr; 51 | 52 | }; 53 | 54 | 55 | 56 | #endif // FLUENTTITLEBAR_H 57 | -------------------------------------------------------------------------------- /src/Card/SampleCard.h: -------------------------------------------------------------------------------- 1 | #ifndef SAMPLE_CARD_H 2 | #define SAMPLE_CARD_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #include "QFluent/CardWidget.h" 12 | #include "QFluent/layout/FlowLayout.h" 13 | 14 | class IconWidget; 15 | class FlowLayout; 16 | class CardWidget; 17 | 18 | class SampleCard : public CardWidget 19 | { 20 | Q_OBJECT 21 | 22 | public: 23 | SampleCard(const QIcon &icon, const QString &title, const QString &content, 24 | const QString &routeKey, int index, QWidget *parent = nullptr); 25 | 26 | signals: 27 | void clicked(const QString &routeKey, int index); 28 | 29 | protected: 30 | void mouseReleaseEvent(QMouseEvent *event) override; 31 | 32 | private: 33 | int m_index; 34 | QString m_routeKey; 35 | IconWidget *m_iconWidget; 36 | QLabel *m_titleLabel; 37 | QLabel *m_contentLabel; 38 | 39 | void initWidget(); 40 | }; 41 | 42 | class SampleCardView : public QWidget 43 | { 44 | Q_OBJECT 45 | 46 | public: 47 | explicit SampleCardView(const QString &title, QWidget *parent = nullptr); 48 | 49 | void addSampleCard(const QIcon &icon, const QString &title, const QString &content, 50 | const QString &routeKey, int index); 51 | void addSampleCard(const QString &iconPath, const QString &title, const QString &content, 52 | const QString &routeKey, int index); 53 | 54 | signals: 55 | void clicked(const QString &routeKey, int index); 56 | 57 | private: 58 | QLabel *m_titleLabel; 59 | QVBoxLayout *m_vBoxLayout; 60 | FlowLayout *m_flowLayout; 61 | 62 | void initWidget(); 63 | void createFlowLayout(); 64 | }; 65 | 66 | #endif // SAMPLE_CARD_H 67 | -------------------------------------------------------------------------------- /libs/include/QFluent/progress/IndeterminateProgressBar.h: -------------------------------------------------------------------------------- 1 | #ifndef INDETERMINATEPROGRESSBAR_H 2 | #define INDETERMINATEPROGRESSBAR_H 3 | 4 | #include 5 | #include "FluentGlobal.h" 6 | 7 | class QPropertyAnimation; 8 | class QParallelAnimationGroup; 9 | class QSequentialAnimationGroup; 10 | class QFLUENT_EXPORT IndeterminateProgressBar : public QProgressBar 11 | { 12 | Q_OBJECT 13 | Q_PROPERTY(qreal shortPos READ shortPos WRITE setShortPos) 14 | Q_PROPERTY(qreal longPos READ longPos WRITE setLongPos) 15 | 16 | public: 17 | explicit IndeterminateProgressBar(QWidget *parent = nullptr, bool start = true); 18 | ~IndeterminateProgressBar(); 19 | 20 | QColor lightBarColor() const; 21 | QColor darkBarColor() const; 22 | 23 | void setCustomBarColor(const QColor &light, const QColor &dark); 24 | 25 | qreal shortPos() const; 26 | void setShortPos(qreal pos); 27 | 28 | qreal longPos() const; 29 | void setLongPos(qreal pos); 30 | 31 | void start(); 32 | void stop(); 33 | bool isStarted() const; 34 | 35 | void pause(); 36 | void resume(); 37 | void setPaused(bool isPaused); 38 | bool isPaused() const; 39 | 40 | void error(); 41 | void setError(bool isError); 42 | bool isError() const; 43 | 44 | protected: 45 | void paintEvent(QPaintEvent *e) override; 46 | 47 | private: 48 | QColor barColor() const; 49 | 50 | qreal m_shortPos = 0; 51 | qreal m_longPos = 0; 52 | 53 | QPropertyAnimation *m_shortBarAni = nullptr; 54 | QPropertyAnimation *m_longBarAni = nullptr; 55 | 56 | QColor m_lightBarColor; 57 | QColor m_darkBarColor; 58 | 59 | bool m_isError = false; 60 | 61 | QParallelAnimationGroup *m_aniGroup = nullptr; 62 | QSequentialAnimationGroup *m_longBarAniGroup = nullptr; 63 | }; 64 | 65 | #endif // INDETERMINATEPROGRESSBAR_H 66 | -------------------------------------------------------------------------------- /libs/include/QFluent/menu/RoundMenu.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "FluentGlobal.h" 10 | 11 | class QListWidgetItem; 12 | class RoundMenuPrivate; 13 | class MenuActionListWidget; 14 | 15 | class QFLUENT_EXPORT RoundMenu : public QMenu 16 | { 17 | Q_OBJECT 18 | Q_DECLARE_PRIVATE_D(dPtr, RoundMenu) 19 | 20 | public: 21 | explicit RoundMenu(const QString &title = QString(), QWidget *parent = nullptr); 22 | ~RoundMenu() override; 23 | 24 | void setItemHeight(int height); 25 | void setMaxVisibleItems(int num); 26 | 27 | void addAction(QAction *action); 28 | void insertAction(QAction *before, QAction *action); 29 | void removeAction(QAction *action); 30 | 31 | void addMenu(RoundMenu *menu); 32 | void insertMenu(QAction *before, RoundMenu *menu); 33 | void removeMenu(RoundMenu *menu); 34 | 35 | void addSeparator(); 36 | void clear(); 37 | void addWidget(QWidget *widget, bool selectable = false); 38 | 39 | QList menuActions() const; 40 | void setDefaultAction(QAction *action); 41 | 42 | MenuActionListWidget *view() const; 43 | void adjustMenuSize(); 44 | int itemHeight() const; 45 | 46 | void setHideByClick(bool enabled); 47 | 48 | void hideMenu(bool isHideBySystem = false); 49 | void exec(const QPoint &pos, bool animate = true, 50 | Fluent::MenuAnimation aniType = Fluent::MenuAnimation::DROP_DOWN); 51 | 52 | signals: 53 | void closed(); 54 | 55 | protected: 56 | void closeEvent(QCloseEvent *event) override; 57 | void paintEvent(QPaintEvent *event) override; 58 | void mouseMoveEvent(QMouseEvent *event) override; 59 | void mousePressEvent(QMouseEvent *event) override; 60 | 61 | virtual int adjustItemText(QListWidgetItem *item, QAction *action); 62 | 63 | private: 64 | QScopedPointer dPtr; 65 | }; 66 | -------------------------------------------------------------------------------- /libs/include/QFluent/progress/IndeterminateProgressRing.h: -------------------------------------------------------------------------------- 1 | #ifndef INDETERMINATE_PROGRESS_RING_H 2 | #define INDETERMINATE_PROGRESS_RING_H 3 | 4 | #include 5 | 6 | #include "FluentGlobal.h" 7 | 8 | class QPropertyAnimation; 9 | class QParallelAnimationGroup; 10 | class QSequentialAnimationGroup; 11 | class QFLUENT_EXPORT IndeterminateProgressRing : public QProgressBar 12 | { 13 | Q_OBJECT 14 | Q_PROPERTY(int startAngle READ startAngle WRITE setStartAngle) 15 | Q_PROPERTY(int spanAngle READ spanAngle WRITE setSpanAngle) 16 | Q_PROPERTY(int strokeWidth READ strokeWidth WRITE setStrokeWidth) 17 | 18 | public: 19 | explicit IndeterminateProgressRing(QWidget *parent = nullptr, bool start = true); 20 | ~IndeterminateProgressRing(); 21 | 22 | int startAngle() const; 23 | void setStartAngle(int angle); 24 | 25 | int spanAngle() const; 26 | void setSpanAngle(int angle); 27 | 28 | int strokeWidth() const; 29 | void setStrokeWidth(int w); 30 | 31 | void start(); 32 | void stop(); 33 | 34 | QColor lightBarColor() const; 35 | QColor darkBarColor() const; 36 | 37 | void setCustomBarColor(const QColor &light, const QColor &dark); 38 | void setCustomBackgroundColor(const QColor &light, const QColor &dark); 39 | 40 | protected: 41 | void paintEvent(QPaintEvent *event) override; 42 | 43 | private: 44 | QColor lightBackgroundColor; 45 | QColor darkBackgroundColor; 46 | QColor _lightBarColor; 47 | QColor _darkBarColor; 48 | int _strokeWidth; 49 | int _startAngle; 50 | int _spanAngle; 51 | 52 | QPropertyAnimation *startAngleAni1; 53 | QPropertyAnimation *startAngleAni2; 54 | QPropertyAnimation *spanAngleAni1; 55 | QPropertyAnimation *spanAngleAni2; 56 | 57 | QSequentialAnimationGroup *startAngleAniGroup; 58 | QSequentialAnimationGroup *spanAngleAniGroup; 59 | QParallelAnimationGroup *aniGroup; 60 | 61 | }; 62 | 63 | #endif // INDETERMINATE_PROGRESS_RING_H 64 | -------------------------------------------------------------------------------- /libs/include/QFluent/TextEdit.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #include "FluentGlobal.h" 12 | // ============================================================ 13 | // EditLayer 14 | // ============================================================ 15 | class EditLayer : public QWidget 16 | { 17 | Q_OBJECT 18 | 19 | public: 20 | explicit EditLayer(QWidget *parent); 21 | 22 | protected: 23 | bool eventFilter(QObject *obj, QEvent *e) override; 24 | void paintEvent(QPaintEvent *e) override; 25 | }; 26 | 27 | // ============================================================ 28 | // TextEdit 29 | // ============================================================ 30 | class QFLUENT_EXPORT TextEdit : public QTextEdit 31 | { 32 | Q_OBJECT 33 | 34 | public: 35 | explicit TextEdit(QWidget *parent = nullptr); 36 | 37 | protected: 38 | void contextMenuEvent(QContextMenuEvent *e) override; 39 | 40 | private: 41 | EditLayer *layer = nullptr; 42 | }; 43 | 44 | // ============================================================ 45 | // PlainTextEdit 46 | // ============================================================ 47 | class QFLUENT_EXPORT PlainTextEdit : public QPlainTextEdit 48 | { 49 | Q_OBJECT 50 | 51 | public: 52 | explicit PlainTextEdit(QWidget *parent = nullptr); 53 | 54 | protected: 55 | void contextMenuEvent(QContextMenuEvent *e) override; 56 | 57 | private: 58 | EditLayer *layer = nullptr; 59 | }; 60 | 61 | // ============================================================ 62 | // TextBrowser 63 | // ============================================================ 64 | class QFLUENT_EXPORT TextBrowser : public QTextBrowser 65 | { 66 | Q_OBJECT 67 | 68 | public: 69 | explicit TextBrowser(QWidget *parent = nullptr); 70 | 71 | protected: 72 | void contextMenuEvent(QContextMenuEvent *e) override; 73 | 74 | private: 75 | EditLayer *layer = nullptr; 76 | }; 77 | -------------------------------------------------------------------------------- /src/Window/SplitWindow.cpp: -------------------------------------------------------------------------------- 1 | #include "SplitWindow.h" 2 | 3 | #include 4 | 5 | #include "StyleSheet.h" 6 | #include "QFluent/Label.h" 7 | #include "QFluent/StackedWidget.h" 8 | #include "QFluent/navigation/NavigationBar.h" 9 | 10 | SplitWidget::SplitWidget() 11 | { 12 | 13 | setWindowButtonHints(Fluent::WindowButtonHint::Icon | Fluent::WindowButtonHint::Title | 14 | Fluent::WindowButtonHint::Minimize | Fluent::WindowButtonHint::Maximize | 15 | Fluent::WindowButtonHint::Close | Fluent::WindowButtonHint::RouteBack); 16 | 17 | setWindowEffect(Fluent::WindowEffect::Normal); 18 | 19 | setContentsMargins(0, 0, 0, 0); 20 | 21 | resize(800, 600); 22 | 23 | initUI(); 24 | } 25 | 26 | void SplitWidget::initUI() 27 | { 28 | setWindowTitle("QFluentKit"); 29 | setWindowIcon(QPixmap(":/res/example.png")); 30 | 31 | navigationInterface()->avatarWidget()->hide(); 32 | navigationInterface()->setExpandWidth(200); 33 | 34 | addSubInterface("1", FluentIcon(Fluent::IconType::HOME), "主页", createWidget("主页", this), true, Fluent::NavigationItemPosition::TOP); 35 | navigationInterface()->addSeparator(); 36 | addSubInterface("3", FluentIcon(Fluent::IconType::CHECKBOX), "输入", createWidget("输入", this), true, Fluent::NavigationItemPosition::SCROLL); 37 | addSubInterface("4", FluentIcon(Fluent::IconType::DATE_TIME), "日期", createWidget("日期", this), true, Fluent::NavigationItemPosition::SCROLL); 38 | navigationInterface()->addSeparator(Fluent::NavigationItemPosition::BOTTOM); 39 | addSubInterface("5", FluentIcon(Fluent::IconType::SETTING), "设置", createWidget("设置", this), true, Fluent::NavigationItemPosition::BOTTOM); 40 | 41 | navigationInterface()->setCurrentItem("1"); 42 | 43 | } 44 | 45 | QWidget* SplitWidget::createWidget(const QString &text, QWidget* parent) 46 | { 47 | auto w = new QWidget(parent); 48 | auto hLay = new QHBoxLayout(w); 49 | auto label = new DisplayLabel(text, w); 50 | label->setAlignment(Qt::AlignCenter); 51 | hLay->addWidget(label); 52 | return w; 53 | } 54 | -------------------------------------------------------------------------------- /libs/include/Router.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "FluentGlobal.h" 8 | 9 | class StackedWidget; 10 | class RouteItem 11 | { 12 | public: 13 | RouteItem() = default; 14 | RouteItem(StackedWidget* stacked, const QString& routeKey) 15 | : stacked(stacked), routeKey(routeKey) {} 16 | 17 | bool operator==(const RouteItem& other) const 18 | { 19 | return stacked == other.stacked && routeKey == other.routeKey; 20 | } 21 | 22 | StackedWidget* stacked{nullptr}; // 改回原始指针 23 | QString routeKey; 24 | }; 25 | 26 | class StackedHistory : public QObject 27 | { 28 | Q_OBJECT 29 | public: 30 | explicit StackedHistory(StackedWidget* stacked, QObject* parent = nullptr); 31 | 32 | void setDefaultRouteKey(const QString& routeKey); 33 | bool push(const QString& routeKey); 34 | void pop(); 35 | void remove(const QString& routeKey); 36 | QString top() const; 37 | bool isEmpty() const; 38 | void goToTop(); 39 | 40 | private: 41 | StackedWidget* m_stacked{nullptr}; 42 | QString m_defaultRouteKey; 43 | QStringList m_history; 44 | }; 45 | 46 | class QFLUENT_EXPORT Router : public QObject 47 | { 48 | Q_OBJECT 49 | 50 | public: 51 | static Router* instance(); 52 | static void destroyInstance(); 53 | 54 | Router(const Router&) = delete; 55 | Router& operator=(const Router&) = delete; 56 | 57 | void setDefaultRouteKey(StackedWidget* stacked, const QString& routeKey); 58 | void push(StackedWidget* stacked, const QString& routeKey); 59 | void pop(); 60 | void remove(const QString& routeKey); 61 | 62 | signals: 63 | void emptyChanged(bool empty); 64 | 65 | private: 66 | explicit Router(QObject* parent = nullptr); 67 | ~Router() override = default; 68 | 69 | void cleanupStackedHistory(StackedWidget* stacked); 70 | 71 | private: 72 | static Router* s_instance; 73 | 74 | QList m_globalHistory; 75 | QMap m_stackHistories; 76 | }; 77 | 78 | #define qrouter Router::instance() 79 | -------------------------------------------------------------------------------- /libs/include/QFluent/menu/MenuAnimation.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "FluentGlobal.h" 8 | 9 | class RoundMenu; 10 | class QPropertyAnimation; 11 | class QPoint; 12 | template class QMap; 13 | 14 | class MenuAnimationManager : public QObject 15 | { 16 | Q_OBJECT 17 | 18 | public: 19 | explicit MenuAnimationManager(RoundMenu* menu, QObject* parent = nullptr); 20 | virtual ~MenuAnimationManager() = default; 21 | 22 | virtual void exec(const QPoint& pos) = 0; 23 | 24 | void updateMenuViewport(); 25 | 26 | static void registerManager(Fluent::MenuAnimation type, 27 | std::function creator); 28 | static MenuAnimationManager* make(RoundMenu* menu, Fluent::MenuAnimation aniType); 29 | 30 | protected: 31 | virtual QPoint endPosition(const QPoint& pos) const; 32 | virtual std::pair menuSize() const; 33 | virtual void onValueChanged(); 34 | 35 | RoundMenu* menu() const; 36 | QPropertyAnimation* animation() const; 37 | bool isMenuValid() const; 38 | 39 | private: 40 | QPointer m_menu; 41 | QPropertyAnimation* m_ani; 42 | }; 43 | 44 | class DummyMenuAnimationManager : public MenuAnimationManager 45 | { 46 | Q_OBJECT 47 | public: 48 | explicit DummyMenuAnimationManager(RoundMenu* menu, QObject* parent = nullptr); 49 | void exec(const QPoint& pos) override; 50 | }; 51 | 52 | class DropDownMenuAnimationManager : public MenuAnimationManager 53 | { 54 | Q_OBJECT 55 | public: 56 | explicit DropDownMenuAnimationManager(RoundMenu* menu, QObject* parent = nullptr); 57 | void exec(const QPoint& pos) override; 58 | 59 | protected: 60 | void onValueChanged() override; 61 | }; 62 | 63 | class PullUpMenuAnimationManager : public MenuAnimationManager 64 | { 65 | Q_OBJECT 66 | public: 67 | explicit PullUpMenuAnimationManager(RoundMenu* menu, QObject* parent = nullptr); 68 | void exec(const QPoint& pos) override; 69 | 70 | protected: 71 | QPoint endPosition(const QPoint& pos) const override; 72 | }; 73 | -------------------------------------------------------------------------------- /libs/include/QFluent/MultiViewComboBox.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "FluentGlobal.h" 10 | 11 | class ComboBoxMenu; 12 | class MultiViewComboBoxPrivate; 13 | class QFLUENT_EXPORT MultiViewComboBox : public QPushButton 14 | { 15 | Q_OBJECT 16 | Q_DECLARE_PRIVATE(MultiViewComboBox) 17 | 18 | public: 19 | explicit MultiViewComboBox(QWidget *parent = nullptr); 20 | ~MultiViewComboBox(); 21 | 22 | // 添加项目 23 | void addItem(const QString &text, 24 | const QIcon &icon = QIcon(), 25 | const QVariant &userData = QVariant()); 26 | void addItems(const QStringList &texts); 27 | 28 | // 插入项目 29 | void insertItem(int index, const QString &text, 30 | const QIcon &icon = QIcon(), 31 | const QVariant &userData = QVariant()); 32 | void insertItems(int index, const QStringList &texts); 33 | 34 | // 移除项目 35 | void removeItem(int index); 36 | void clear(); 37 | 38 | // 选中管理 39 | void setItemSelected(int index, bool selected); 40 | bool isItemSelected(int index) const; 41 | QList selectedIndexes() const; 42 | QStringList selectedTexts() const; 43 | QList selectedDatas() const; 44 | 45 | // 项目访问 46 | int count() const; 47 | QString itemText(int index) const; 48 | QIcon itemIcon(int index) const; 49 | QVariant itemData(int index) const; 50 | 51 | // 查找 52 | int findText(const QString &text) const; 53 | int findData(const QVariant &data) const; 54 | 55 | // 设置占位文本 56 | void setPlaceholderText(const QString &text); 57 | QString placeholderText() const; 58 | 59 | void setMaxVisibleItems(int count); 60 | int maxVisibleItems() const; 61 | 62 | signals: 63 | void selectionChanged(); 64 | 65 | protected: 66 | void paintEvent(QPaintEvent *event) override; 67 | void mouseReleaseEvent(QMouseEvent *event) override; 68 | bool eventFilter(QObject *watched, QEvent *event) override; 69 | 70 | private: 71 | QScopedPointer d_ptr; 72 | }; 73 | -------------------------------------------------------------------------------- /res/icons/EmojiTabSymbols_black.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /res/icons/EmojiTabSymbols_white.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /libs/include/QFluent/ScrollArea.h: -------------------------------------------------------------------------------- 1 | #ifndef SCROLLAREA_H 2 | #define SCROLLAREA_H 3 | 4 | #include 5 | #include 6 | #include "FluentGlobal.h" 7 | 8 | class SmoothScrollDelegate; 9 | class SmoothScroll; 10 | class SmoothScrollBar; 11 | 12 | class QFLUENT_EXPORT ScrollArea : public QScrollArea 13 | { 14 | Q_OBJECT 15 | 16 | public: 17 | explicit ScrollArea(QWidget *parent = nullptr); 18 | 19 | void setSmoothMode(Fluent::SmoothMode smoothMode, Qt::Orientation orientation = Qt::Vertical); 20 | void enableTransparentBackground(); 21 | void setViewportMargins(int left, int top, int right, int bottom); 22 | 23 | private: 24 | SmoothScrollDelegate *m_scrollDelegate; 25 | }; 26 | 27 | // ===================== SingleDirectionScrollArea ===================== 28 | class QFLUENT_EXPORT SingleDirectionScrollArea : public QScrollArea 29 | { 30 | Q_OBJECT 31 | 32 | public: 33 | explicit SingleDirectionScrollArea(QWidget *parent = nullptr, Qt::Orientation orient = Qt::Vertical); 34 | 35 | void setSmoothMode(Fluent::SmoothMode mode); 36 | void enableTransparentBackground(); 37 | void setViewportMargins(int left, int top, int right, int bottom); 38 | 39 | // 重写策略,强制另一方向永远不显示滚动条 40 | void setVerticalScrollBarPolicy(Qt::ScrollBarPolicy policy); 41 | void setHorizontalScrollBarPolicy(Qt::ScrollBarPolicy policy); 42 | 43 | protected: 44 | void wheelEvent(QWheelEvent *e) override; 45 | void keyPressEvent(QKeyEvent *e) override; 46 | 47 | private: 48 | Qt::Orientation m_orient; 49 | SmoothScroll *m_smoothScroll; 50 | SmoothScrollBar *m_vScrollBar; // 自定义垂直滚动条 51 | SmoothScrollBar *m_hScrollBar; // 自定义水平滚动条 52 | }; 53 | 54 | // ===================== SmoothScrollArea ===================== 55 | class QFLUENT_EXPORT SmoothScrollArea : public QScrollArea 56 | { 57 | Q_OBJECT 58 | 59 | public: 60 | explicit SmoothScrollArea(QWidget *parent = nullptr); 61 | 62 | void setScrollAnimation(Qt::Orientation orient, int duration, QEasingCurve::Type easing = QEasingCurve::OutCubic); 63 | void enableTransparentBackground(); 64 | 65 | private: 66 | SmoothScrollDelegate *m_delegate; 67 | }; 68 | 69 | #endif // SCROLLAREA_H 70 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | QFluentKit Free Binary License 2 | Version 1.0, 2025 3 | 4 | Copyright (c) 2025 Todd. All rights reserved. 5 | 6 | This license applies solely to the compiled binary form of QFluentKit 7 | (e.g., QFluentKit.dll, libQFluentKit.so, or other distributed binary files). 8 | The source code of QFluentKit is not provided and remains proprietary. 9 | 10 | GRANT OF LICENSE: 11 | You are hereby granted a free, non-exclusive, worldwide, royalty-free right to: 12 | - Use QFluentKit in your applications, whether for personal, educational, or commercial purposes; 13 | - Distribute the QFluentKit binary alongside your application, provided that this license file 14 | and the above copyright notice are included unmodified in your distribution. 15 | 16 | RESTRICTIONS: 17 | You may NOT: 18 | - Reverse engineer, decompile, disassemble, or otherwise attempt to derive the source code; 19 | - Modify, adapt, merge, or create derivative works based on QFluentKit; 20 | - Redistribute QFluentKit as a standalone library, software development kit (SDK), 21 | or as part of a competing product without explicit written permission from the author. 22 | 23 | DISCLAIMER OF WARRANTY: 24 | QFLUENTKIT IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 25 | INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 26 | PURPOSE, AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHOR OR COPYRIGHT HOLDER BE LIABLE 27 | FOR ANY CLAIM, DAMAGES, OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT, 28 | OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE USE OF OR INABILITY TO USE 29 | QFLUENTKIT. 30 | 31 | NOTICE REGARDING Qt: 32 | QFluentKit is built using the Qt framework, which is licensed under the GNU Lesser 33 | General Public License (LGPL) version 3. As required by the LGPL, you have the right to: 34 | - Obtain the complete corresponding source code of the Qt libraries used by QFluentKit 35 | from https://www.qt.io/ or https://code.qt.io/; 36 | - Replace the Qt libraries with a modified or updated version compatible with QFluentKit. 37 | 38 | This license does not impose any open-source obligations on your own application, 39 | provided you comply with the terms of the Qt LGPL regarding dynamic linking. 40 | 41 | —— End of License —— -------------------------------------------------------------------------------- /libs/include/QFluent/ComboBox.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "FluentGlobal.h" 9 | 10 | class ComboBoxMenu; 11 | class ComboBoxPrivate; 12 | class QFLUENT_EXPORT ComboBox : public QPushButton 13 | { 14 | Q_OBJECT 15 | Q_DECLARE_PRIVATE(ComboBox) 16 | 17 | public: 18 | explicit ComboBox(QWidget *parent = nullptr); 19 | ~ComboBox(); 20 | 21 | // 添加项目 22 | void addItem(const QString &text, 23 | const QIcon &icon = QIcon(), 24 | const QVariant &userData = QVariant()); 25 | void addItems(const QStringList &texts); 26 | 27 | // 插入项目 28 | void insertItem(int index, const QString &text, 29 | const QIcon &icon = QIcon(), 30 | const QVariant &userData = QVariant()); 31 | void insertItems(int index, const QStringList &texts); 32 | 33 | // 移除项目 34 | void removeItem(int index); 35 | void clear(); 36 | 37 | // 当前选择 38 | int currentIndex() const; 39 | QString currentText() const; 40 | QVariant currentData() const; 41 | 42 | // 设置当前选择 43 | void setCurrentIndex(int index); 44 | void setCurrentText(const QString &text); 45 | 46 | // 项目访问 47 | int count() const; 48 | QString itemText(int index) const; 49 | QIcon itemIcon(int index) const; 50 | QVariant itemData(int index) const; 51 | 52 | // 查找 53 | int findText(const QString &text) const; 54 | int findData(const QVariant &data) const; 55 | 56 | // 设置占位文本 57 | void setPlaceholderText(const QString &text); 58 | QString placeholderText() const; 59 | 60 | void setText(const QString &text); 61 | 62 | void setMaxVisibleItems(int count); 63 | 64 | int maxVisibleItems() const; 65 | 66 | signals: 67 | void currentIndexChanged(int index); 68 | void currentTextChanged(const QString &text); 69 | void activated(int index); 70 | void textActivated(const QString &text); 71 | 72 | protected: 73 | void paintEvent(QPaintEvent *event) override; 74 | void mouseReleaseEvent(QMouseEvent *event) override; 75 | bool eventFilter(QObject *watched, QEvent *event) override; 76 | 77 | private: 78 | QScopedPointer d_ptr; 79 | }; 80 | -------------------------------------------------------------------------------- /libs/include/QFluent/EditableComboBox.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include "LineEdit.h" 7 | #include "FluentGlobal.h" 8 | 9 | class ComboBoxMenu; 10 | class EditableComboBoxPrivate; 11 | class QFLUENT_EXPORT EditableComboBox : public LineEdit 12 | { 13 | Q_OBJECT 14 | Q_DECLARE_PRIVATE(EditableComboBox) 15 | 16 | public: 17 | explicit EditableComboBox(QWidget *parent = nullptr); 18 | ~EditableComboBox(); 19 | 20 | // 添加项目 21 | void addItem(const QString &text, 22 | const QIcon &icon = QIcon(), 23 | const QVariant &userData = {}); 24 | void addItems(const QStringList &texts); 25 | 26 | // 插入项目 27 | void insertItem(int index, const QString &text, 28 | const QIcon &icon = QIcon(), 29 | const QVariant &userData = {}); 30 | void insertItems(int index, const QStringList &texts); 31 | 32 | // 移除项目 33 | void removeItem(int index); 34 | void clear(); 35 | 36 | // 当前选择 37 | int currentIndex() const; 38 | QString currentText() const; 39 | QVariant currentData() const; 40 | 41 | // 设置当前选择 42 | void setCurrentIndex(int index); 43 | void setCurrentText(const QString &text); 44 | 45 | // 项目访问 46 | int count() const; 47 | QString itemText(int index) const; 48 | QIcon itemIcon(int index) const; 49 | QVariant itemData(int index) const; 50 | 51 | // 查找 52 | int findText(const QString &text) const; 53 | int findData(const QVariant &data) const; 54 | 55 | // 设置占位文本 56 | void setPlaceholderText(const QString &text); 57 | QString placeholderText() const; 58 | 59 | void setText(const QString &text); 60 | 61 | void setCompleterMenu(CompleterMenu *menu); 62 | 63 | void setMaxVisibleItems(int count); 64 | 65 | int maxVisibleItems() const; 66 | 67 | signals: 68 | void currentIndexChanged(int index); 69 | void currentTextChanged(const QString &text); 70 | void activated(int index); 71 | void textActivated(const QString &text); 72 | 73 | protected: 74 | void paintEvent(QPaintEvent *event) override; 75 | void mouseReleaseEvent(QMouseEvent *event) override; 76 | bool eventFilter(QObject *watched, QEvent *event) override; 77 | 78 | private: 79 | QScopedPointer d_ptr; 80 | }; 81 | -------------------------------------------------------------------------------- /src/FluentWindow.h.txt: -------------------------------------------------------------------------------- 1 | #ifndef FLUENTWINDOW_H 2 | #define FLUENTWINDOW_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #include "Property.h" 17 | 18 | #include "Theme.h" 19 | #include "SwitchButton.h" 20 | #include "RadioButton.h" 21 | #include "LineEdit.h" 22 | #include "PushButton.h" 23 | #include "CheckBox.h" 24 | #include "ComboBox.h" 25 | #include "menu/RoundMenu.h" 26 | #include "SpinBox.h" 27 | #include "Label.h" 28 | #include "TableView.h" 29 | #include "InfoBar.h" 30 | #include "dialog/MessageDialog.h" 31 | #include "Loading.h" 32 | #include "ToolButton.h" 33 | #include "PagiNation.h" 34 | #include "navigation/NavigationPanel.h" 35 | #include "StackedWidget.h" 36 | #include "FluentTitleBar.h" 37 | #include "EditableComboBox.h" 38 | #include "date_time/CalendarView.h" 39 | 40 | #include "settings/SettingCard.h" 41 | #include "settings/SettingCardGroup.h" 42 | #include "Icon.h" 43 | #include "layout/ExpandLayout.h" 44 | #include "ScrollArea.h" 45 | #include "settings/OptionsSettingCard.h" 46 | #include "date_time/CalendarPicker.h" 47 | 48 | #include "navigation/Pivot.h" 49 | #include "navigation/NavigationBar.h" 50 | #include "menu/CheckableMenu.h" 51 | 52 | #include "layout/FlowLayout.h" 53 | 54 | #include "progress/ProgressBar.h" 55 | #include "progress/ProgressRing.h" 56 | #include "progress/IndeterminateProgressBar.h" 57 | 58 | #include "dialog/MessageBoxBase.h" 59 | 60 | #include "examples/GalleryInterface.h" 61 | 62 | class QFLUENT_EXPORT FluentWindow : public QMainWindow 63 | { 64 | Q_OBJECT 65 | 66 | public: 67 | FluentWindow(QMainWindow *parent = nullptr); 68 | ~FluentWindow(); 69 | 70 | protected: 71 | bool event(QEvent *event) override; 72 | 73 | private: 74 | void installAgent(); 75 | 76 | void initUI(); 77 | 78 | void loadStyleSheet(bool); 79 | 80 | QObject *windowAgent{nullptr}; 81 | 82 | QStackedWidget *stackedWidget{nullptr}; 83 | 84 | void switchTo(QWidget *w); 85 | 86 | StackedWidget *stacked; 87 | 88 | FlowLayout *m_flay; 89 | 90 | QList m_btns; 91 | 92 | ProgressBar *m_progressBar; 93 | }; 94 | #endif // FLUENTWINDOW_H 95 | -------------------------------------------------------------------------------- /libs/include/QFluent/layout/FlowLayout.h: -------------------------------------------------------------------------------- 1 | #ifndef FLOWLAYOUT_H 2 | #define FLOWLAYOUT_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include "FluentGlobal.h" 9 | 10 | QT_BEGIN_NAMESPACE 11 | 12 | class QPropertyAnimation; 13 | class QParallelAnimationGroup; 14 | class QFLUENT_EXPORT FlowLayout : public QLayout 15 | { 16 | Q_OBJECT 17 | Q_DISABLE_COPY(FlowLayout) 18 | 19 | public: 20 | explicit FlowLayout(QWidget *parent = nullptr, bool needAni = false, bool isTight = false); 21 | ~FlowLayout(); 22 | 23 | void addItem(QLayoutItem *item) override; 24 | void insertItem(int index, QLayoutItem *item); 25 | void addWidget(QWidget *widget); 26 | void insertWidget(int index, QWidget *widget); 27 | void setAnimation(int duration, QEasingCurve::Type ease = QEasingCurve::Linear); 28 | 29 | int count() const override; 30 | QLayoutItem *itemAt(int index) const override; 31 | QLayoutItem *takeAt(int index) override; 32 | void removeWidget(QWidget *widget); 33 | 34 | void removeAllWidgets(); 35 | void takeAllWidgets(); 36 | 37 | Qt::Orientations expandingDirections() const override; 38 | bool hasHeightForWidth() const override; 39 | int heightForWidth(int width) const override; 40 | 41 | QSize sizeHint() const override; 42 | QSize minimumSize() const override; 43 | 44 | void setVerticalSpacing(int spacing); 45 | int verticalSpacing() const; 46 | void setHorizontalSpacing(int spacing); 47 | int horizontalSpacing() const; 48 | 49 | protected: 50 | bool eventFilter(QObject *object, QEvent *event) override; 51 | void setGeometry(const QRect &rect) override; 52 | 53 | private: 54 | QVector _items; 55 | QVector _animations; 56 | QParallelAnimationGroup *_aniGroup; 57 | int _verticalSpacing; 58 | int _horizontalSpacing; 59 | int _duration; 60 | QEasingCurve::Type _ease; 61 | bool _needAni; 62 | bool _isTight; 63 | QTimer *_debounceTimer; 64 | QWidget *_wParent; 65 | bool _isInstalledEventFilter; 66 | 67 | void _onWidgetAdded(QWidget *widget, int index = -1); 68 | int _calculateHeight(const QRect &rect) const; // 新增:const 方法,仅计算高度 69 | int _doLayout(const QRect &rect, bool move); // 保持非 const,用于实际布局 70 | }; 71 | 72 | QT_END_NAMESPACE 73 | 74 | #endif // FLOWLAYOUT_H 75 | -------------------------------------------------------------------------------- /libs/include/QFluent/date_time/CycleListWidget.h: -------------------------------------------------------------------------------- 1 | #ifndef CYCLE_LIST_WIDGET_H 2 | #define CYCLE_LIST_WIDGET_H 3 | 4 | #include 5 | #include 6 | #include "FluentIcon.h" 7 | 8 | class ScrollButton : public QToolButton 9 | { 10 | Q_OBJECT 11 | 12 | public: 13 | explicit ScrollButton(const FluentIconBase &icon, QWidget* parent = nullptr); 14 | 15 | protected: 16 | bool eventFilter(QObject* obj, QEvent* e) override; 17 | void paintEvent(QPaintEvent* e) override; 18 | 19 | private: 20 | bool m_isPressed; 21 | std::unique_ptr m_fluentIcon; 22 | }; 23 | 24 | class SmoothScrollBar; 25 | class CycleListWidget : public QListWidget 26 | { 27 | Q_OBJECT 28 | 29 | public: 30 | explicit CycleListWidget(const QStringList& items, const QSize& itemSize, 31 | Qt::Alignment align = Qt::AlignCenter, QWidget* parent = nullptr); 32 | 33 | void setItems(const QStringList& items); 34 | void setSelectedItem(const QString& text); 35 | void scrollToItem(QListWidgetItem* item, QAbstractItemView::ScrollHint hint = QAbstractItemView::PositionAtCenter); 36 | 37 | QListWidgetItem* currentItem(); 38 | int currentIndex() const { return m_currentIndex; } 39 | void setCurrentIndex(int index); 40 | 41 | signals: 42 | void currentItemChanged(QListWidgetItem* item); 43 | 44 | public slots: 45 | void scrollDown(); 46 | void scrollUp(); 47 | 48 | protected: 49 | void wheelEvent(QWheelEvent* e) override; 50 | #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) 51 | void enterEvent(QEnterEvent *e) override; 52 | #else 53 | void enterEvent(QEvent *e) override; 54 | #endif 55 | void leaveEvent(QEvent* e) override; 56 | void resizeEvent(QResizeEvent* e) override; 57 | bool eventFilter(QObject* obj, QEvent* e) override; 58 | 59 | private slots: 60 | void onItemClicked(QListWidgetItem* item); 61 | 62 | private: 63 | void createItems(const QStringList& items); 64 | void addColumnItems(const QStringList& items, bool disabled = false); 65 | 66 | QSize m_itemSize; 67 | Qt::Alignment m_align; 68 | ScrollButton* m_upButton; 69 | ScrollButton* m_downButton; 70 | int m_scrollDuration; 71 | QStringList m_originItems; 72 | SmoothScrollBar* m_vScrollBar; 73 | int m_visibleNumber; 74 | int m_currentIndex; 75 | bool m_isCycle; 76 | }; 77 | 78 | 79 | #endif // CYCLE_LIST_WIDGET_H 80 | -------------------------------------------------------------------------------- /res/icons/Menu_black.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /res/icons/Menu_white.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /libs/include/QFluent/Label.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "FluentGlobal.h" 6 | 7 | class QFLUENT_EXPORT FluentLabelBase : public QLabel { 8 | Q_OBJECT 9 | 10 | public: 11 | explicit FluentLabelBase(int fontSize = 14, QFont::Weight weight = QFont::Normal, QWidget* parent = nullptr); 12 | explicit FluentLabelBase(const QString& text, int fontSize = 14, QFont::Weight weight = QFont::Normal, QWidget* parent = nullptr); 13 | 14 | int pixelFontSize() const; 15 | 16 | bool strikeOut() const; 17 | 18 | bool underline() const; 19 | 20 | void setTextColor(const QColor& lightColor, const QColor& darkColor); 21 | 22 | void setPixelFontSize(int size); 23 | void setStrikeOut(bool isStrikeOut); 24 | void setUnderline(bool isUnderline); 25 | 26 | }; 27 | 28 | class QFLUENT_EXPORT CaptionLabel : public FluentLabelBase { 29 | Q_OBJECT 30 | public: 31 | explicit CaptionLabel(QWidget* parent = nullptr); 32 | explicit CaptionLabel(const QString& text, QWidget* parent = nullptr); 33 | 34 | }; 35 | 36 | class QFLUENT_EXPORT BodyLabel : public FluentLabelBase { 37 | Q_OBJECT 38 | public: 39 | explicit BodyLabel(QWidget* parent = nullptr); 40 | explicit BodyLabel(const QString& text, QWidget* parent = nullptr); 41 | }; 42 | 43 | class QFLUENT_EXPORT StrongBodyLabel : public FluentLabelBase { 44 | Q_OBJECT 45 | public: 46 | explicit StrongBodyLabel(QWidget* parent = nullptr); 47 | explicit StrongBodyLabel(const QString& text, QWidget* parent = nullptr); 48 | }; 49 | 50 | class QFLUENT_EXPORT SubtitleLabel : public FluentLabelBase { 51 | Q_OBJECT 52 | public: 53 | explicit SubtitleLabel(QWidget* parent = nullptr); 54 | explicit SubtitleLabel(const QString& text, QWidget* parent = nullptr); 55 | }; 56 | 57 | class QFLUENT_EXPORT TitleLabel : public FluentLabelBase { 58 | Q_OBJECT 59 | public: 60 | explicit TitleLabel(QWidget* parent = nullptr); 61 | explicit TitleLabel(const QString& text, QWidget* parent = nullptr); 62 | }; 63 | 64 | class QFLUENT_EXPORT LargeTitleLabel : public FluentLabelBase { 65 | Q_OBJECT 66 | public: 67 | explicit LargeTitleLabel(QWidget* parent = nullptr); 68 | explicit LargeTitleLabel(const QString& text, QWidget* parent = nullptr); 69 | }; 70 | 71 | class QFLUENT_EXPORT DisplayLabel : public FluentLabelBase { 72 | Q_OBJECT 73 | public: 74 | explicit DisplayLabel(QWidget* parent = nullptr); 75 | explicit DisplayLabel(const QString& text, QWidget* parent = nullptr); 76 | }; 77 | -------------------------------------------------------------------------------- /libs/include/QFluent/navigation/Pivot.h: -------------------------------------------------------------------------------- 1 | #ifndef PIVOT_H 2 | #define PIVOT_H 3 | 4 | #include 5 | #include 6 | 7 | #include "FluentIcon.h" 8 | #include "FluentGlobal.h" 9 | #include "QFluent/PushButton.h" 10 | 11 | class QHBoxLayout; 12 | class FluentAnimation; 13 | class PivotItem : public PushButton { 14 | Q_OBJECT 15 | Q_PROPERTY(bool isSelected READ isSelected WRITE setSelected NOTIFY isSelectedChanged) 16 | 17 | public: 18 | explicit PivotItem(const QString &text = QString(), QWidget *parent = nullptr); 19 | bool isSelected() const; 20 | void setSelected(bool isSelected); 21 | 22 | signals: 23 | void itemClicked(bool); 24 | void isSelectedChanged(bool); // 信号定义移到 Q_PROPERTY 之前 25 | 26 | protected: 27 | void paintEvent(QPaintEvent *event) override; 28 | 29 | private: 30 | bool _isSelected = false; 31 | }; 32 | 33 | class QFLUENT_EXPORT Pivot : public QWidget { 34 | Q_OBJECT 35 | Q_PROPERTY(QString currentRouteKey READ currentRouteKey NOTIFY currentRouteKeyChanged) 36 | 37 | public: 38 | explicit Pivot(QWidget *parent = nullptr); 39 | ~Pivot() override; 40 | 41 | void addItem(const QString &routeKey, const QString &text, const FluentIconBase &icon); 42 | void addWidget(const QString &routeKey, PivotItem *widget); 43 | void insertItem(int index, const QString &routeKey, const QString &text, const FluentIconBase &icon); 44 | void insertWidget(int index, const QString &routeKey, PivotItem *widget); 45 | void removeWidget(const QString &routeKey); 46 | void clear(); 47 | PivotItem *currentItem() const; 48 | QString currentRouteKey() const; 49 | void setCurrentItem(const QString &routeKey); 50 | void setItemFontSize(int size); 51 | void setItemText(const QString &routeKey, const QString &text); 52 | void setIndicatorColor(const QColor &light, const QColor &dark); 53 | 54 | signals: 55 | void currentItemChanged(const QString &routeKey); 56 | void currentRouteKeyChanged(const QString &routeKey); 57 | 58 | protected: 59 | void showEvent(QShowEvent *event) override; 60 | void resizeEvent(QResizeEvent *event) override; 61 | void paintEvent(QPaintEvent *event) override; 62 | 63 | private slots: 64 | void _onItemClicked(); 65 | 66 | private: 67 | void _adjustIndicatorPos(); 68 | PivotItem *widget(const QString &routeKey) const; 69 | 70 | QMap items; 71 | QString _currentRouteKey; 72 | QColor lightIndicatorColor; 73 | QColor darkIndicatorColor; 74 | QHBoxLayout *hBoxLayout; 75 | FluentAnimation *slideAni; 76 | }; 77 | 78 | #endif // PIVOT_H 79 | -------------------------------------------------------------------------------- /src/TextInterface.cpp: -------------------------------------------------------------------------------- 1 | #include "TextInterface.h" 2 | 3 | #include 4 | #include "QFluent/LineEdit.h" 5 | #include "QFluent/SpinBox.h" 6 | #include "QFluent/TextEdit.h" 7 | 8 | TextInterface::TextInterface(QWidget *parent) 9 | : GalleryInterface("文本", "", parent) 10 | { 11 | setObjectName("TextInterface"); 12 | 13 | auto lineEdit = new LineEdit(this); 14 | lineEdit->setFixedWidth(230); 15 | lineEdit->setClearButtonEnabled(true); 16 | lineEdit->setText("带清空按钮的输入框"); 17 | addExampleCard("带清空按钮的输入框", lineEdit); 18 | 19 | auto passwordLineEdit = new PasswordLineEdit(this); 20 | passwordLineEdit->setFixedWidth(230); 21 | passwordLineEdit->setViewPasswordButtonVisible(true); 22 | passwordLineEdit->setPlaceholderText("请输入密码"); 23 | addExampleCard("密码输入框", passwordLineEdit); 24 | 25 | QStringList items = { 26 | "Settings", "Profile", 27 | "Dashboard", "Notifications", 28 | "Messages", "Calendar", 29 | "Documents", "Downloads", 30 | "Search", "Help", 31 | "Logout", "Preferences", 32 | "History", "Bookmarks", 33 | "Themes", "Shortcuts", 34 | "Backup", "Sync Now", 35 | "New Tab", "Open File", 36 | "Save As", "Print Preview", 37 | "Export PDF", "Import Data", 38 | "Refresh", "Reload Page", 39 | "Clear Cache", "Developer Tools", 40 | "About App", "Check Updates", 41 | "Send Feedback", "Report Issue" 42 | }; 43 | auto searchLineEdit = new SearchLineEdit(this); 44 | searchLineEdit->setFixedWidth(230); 45 | searchLineEdit->setClearButtonEnabled(true); 46 | searchLineEdit->setPlaceholderText("请输入内容"); 47 | QCompleter *completer = new QCompleter(items, searchLineEdit); 48 | completer->setCaseSensitivity(Qt::CaseInsensitive); 49 | completer->setMaxVisibleItems(5); 50 | searchLineEdit->setCompleter(completer); 51 | 52 | addExampleCard("带补全功能的输入框", searchLineEdit); 53 | addExampleCard("微调框", new SpinBox(this)); 54 | addExampleCard("浮点数微调框", new DoubleSpinBox(this)); 55 | addExampleCard("时间编辑框", new TimeEdit(this)); 56 | addExampleCard("日期编辑框", new DateEdit(this)); 57 | addExampleCard("日期时间编辑框", new DateTimeEdit(this)); 58 | 59 | auto textEdit = new TextEdit(this); 60 | textEdit->setMarkdown("## 演示小队\n" 61 | "* 布局大师 🧱\n" 62 | "* 样式达人 🎨\n" 63 | "* 逻辑鬼才 💡\n" 64 | "* 摸鱼专家 🍵\n" 65 | "* 编译守护 🛡️"); 66 | textEdit->setFixedHeight(150); 67 | addExampleCard("富文本框", textEdit, "", 1); 68 | } 69 | 70 | 71 | -------------------------------------------------------------------------------- /libs/include/QFluent/SwitchButton.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | 7 | #include "FluentGlobal.h" 8 | 9 | class QLabel; 10 | class QHBoxLayout; 11 | class QPropertyAnimation; 12 | class Indicator : public QToolButton { 13 | Q_OBJECT 14 | Q_PROPERTY(qreal sliderX READ sliderX WRITE setSliderX) 15 | 16 | public: 17 | explicit Indicator(QWidget *parent = nullptr); 18 | 19 | signals: 20 | void checkedChanged(bool checked); 21 | 22 | protected: 23 | void mouseReleaseEvent(QMouseEvent *event) override; 24 | void paintEvent(QPaintEvent *event) override; 25 | 26 | private slots: 27 | void toggleSlider(); 28 | 29 | private: 30 | void drawBackground(QPainter &painter); 31 | void drawCircle(QPainter &painter); 32 | QColor backgroundColor() const; 33 | QColor borderColor() const; 34 | QColor sliderColor() const; 35 | 36 | qreal sliderX() const { return m_sliderX; } 37 | void setSliderX(qreal x); 38 | 39 | qreal m_sliderX; 40 | QPropertyAnimation *m_slideAni; 41 | }; 42 | 43 | class QFLUENT_EXPORT SwitchButton : public QWidget { 44 | Q_OBJECT 45 | Q_PROPERTY(bool checked READ isChecked WRITE setChecked) 46 | Q_PROPERTY(QString text READ text WRITE setText) 47 | Q_PROPERTY(QString onText READ onText WRITE setOnText) 48 | Q_PROPERTY(QString offText READ offText WRITE setOffText) 49 | Q_PROPERTY(int spacing READ spacing WRITE setSpacing) 50 | 51 | public: 52 | enum class IndicatorPosition { Left, Right }; 53 | 54 | explicit SwitchButton(QWidget *parent = nullptr, IndicatorPosition indicatorPos = IndicatorPosition::Left); 55 | explicit SwitchButton(const QString &text, QWidget *parent = nullptr, IndicatorPosition indicatorPos = IndicatorPosition::Left); 56 | 57 | bool isChecked() const; 58 | void setChecked(bool checked); 59 | QString text() const; 60 | void setText(const QString &text); 61 | QString onText() const; 62 | void setOnText(const QString &text); 63 | QString offText() const; 64 | void setOffText(const QString &text); 65 | int spacing() const; 66 | void setSpacing(int spacing); 67 | void setCheckedIndicatorColor(const QColor &light, const QColor &dark); 68 | void toggleChecked(); 69 | 70 | signals: 71 | void checkedChanged(bool checked); 72 | 73 | protected: 74 | bool eventFilter(QObject *obj, QEvent *event) override; 75 | 76 | private: 77 | void initWidget(); 78 | void updateText(); 79 | 80 | Indicator *m_indicator; 81 | QLabel *m_label; 82 | QHBoxLayout *m_hBox; 83 | IndicatorPosition m_indicatorPos; 84 | QString m_text; 85 | QString m_onText; 86 | QString m_offText; 87 | int m_spacing; 88 | }; 89 | -------------------------------------------------------------------------------- /libs/include/QFluent/date_time/TimePicker.h: -------------------------------------------------------------------------------- 1 | #ifndef TIME_PICKER_H 2 | #define TIME_PICKER_H 3 | 4 | #include "PickerBase.h" 5 | #include 6 | 7 | #include "FluentGlobal.h" 8 | 9 | class MinuteFormatter : public DigitFormatter 10 | { 11 | Q_OBJECT 12 | 13 | public: 14 | using DigitFormatter::DigitFormatter; 15 | QString encode(const QVariant& value) override; 16 | }; 17 | 18 | class AMHourFormatter : public DigitFormatter 19 | { 20 | Q_OBJECT 21 | 22 | public: 23 | using DigitFormatter::DigitFormatter; 24 | QString encode(const QVariant& value) override; 25 | }; 26 | 27 | class AMPMFormatter : public PickerColumnFormatter 28 | { 29 | Q_OBJECT 30 | 31 | public: 32 | explicit AMPMFormatter(QObject* parent = nullptr); 33 | QString encode(const QVariant& value) override; 34 | 35 | private: 36 | QString m_AM; 37 | QString m_PM; 38 | }; 39 | 40 | class QFLUENT_EXPORT TimePickerBase : public PickerBase 41 | { 42 | Q_OBJECT 43 | Q_PROPERTY(QTime time READ getTime WRITE setTime) 44 | Q_PROPERTY(bool secondVisible READ isSecondVisible WRITE setSecondVisible) 45 | 46 | public: 47 | explicit TimePickerBase(QWidget* parent = nullptr, bool showSeconds = false); 48 | 49 | QTime getTime() const { return m_time; } 50 | virtual void setTime(const QTime& time) = 0; 51 | 52 | bool isSecondVisible() const { return m_isSecondVisible; } 53 | virtual void setSecondVisible(bool isVisible) = 0; 54 | 55 | public slots: 56 | void reset() override; 57 | 58 | signals: 59 | void timeChanged(const QTime& time); 60 | 61 | protected: 62 | bool m_isSecondVisible; 63 | QTime m_time; 64 | }; 65 | 66 | class QFLUENT_EXPORT TimePicker : public TimePickerBase 67 | { 68 | Q_OBJECT 69 | 70 | public: 71 | explicit TimePicker(QWidget* parent = nullptr, bool showSeconds = false); 72 | 73 | void setTime(const QTime& time) override; 74 | void setSecondVisible(bool isVisible) override; 75 | 76 | protected: 77 | QStringList panelInitialValue() override; 78 | void onConfirmed(const QStringList& value) override; 79 | }; 80 | 81 | class QFLUENT_EXPORT AMTimePicker : public TimePickerBase 82 | { 83 | Q_OBJECT 84 | 85 | public: 86 | explicit AMTimePicker(QWidget* parent = nullptr, bool showSeconds = false); 87 | 88 | void setTime(const QTime& time) override; 89 | void setSecondVisible(bool isVisible) override; 90 | 91 | protected: 92 | QStringList panelInitialValue() override; 93 | void onConfirmed(const QStringList& value) override; 94 | 95 | private: 96 | QString m_AM; 97 | QString m_PM; 98 | }; 99 | 100 | #endif // TIME_PICKER_H 101 | -------------------------------------------------------------------------------- /libs/include/QFluent/menu/MenuItemDelegate.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | class QPainter; 6 | class QModelIndex; 7 | class QStyleOptionViewItem; 8 | class QAction; 9 | 10 | class MenuItemDelegate : public QStyledItemDelegate 11 | { 12 | Q_OBJECT 13 | 14 | public: 15 | explicit MenuItemDelegate(QObject *parent = nullptr); 16 | bool isSeparator(const QModelIndex &index) const; 17 | 18 | protected: 19 | void paint(QPainter *painter, 20 | const QStyleOptionViewItem &option, 21 | const QModelIndex &index) const override; 22 | }; 23 | 24 | class ShortcutMenuItemDelegate : public MenuItemDelegate 25 | { 26 | Q_OBJECT 27 | 28 | public: 29 | explicit ShortcutMenuItemDelegate(QObject *parent = nullptr); 30 | 31 | protected: 32 | void paint(QPainter *painter, 33 | const QStyleOptionViewItem &option, 34 | const QModelIndex &index) const override; 35 | }; 36 | 37 | class IndicatorMenuItemDelegate : public MenuItemDelegate 38 | { 39 | Q_OBJECT 40 | 41 | public: 42 | explicit IndicatorMenuItemDelegate(QObject *parent = nullptr); 43 | 44 | protected: 45 | void paint(QPainter *painter, 46 | const QStyleOptionViewItem &option, 47 | const QModelIndex &index) const override; 48 | }; 49 | 50 | class CheckableMenuItemDelegate : public ShortcutMenuItemDelegate 51 | { 52 | Q_OBJECT 53 | 54 | public: 55 | explicit CheckableMenuItemDelegate(QObject *parent = nullptr); 56 | 57 | protected: 58 | void paint(QPainter *painter, 59 | const QStyleOptionViewItem &option, 60 | const QModelIndex &index) const override; 61 | 62 | virtual void drawIndicator(QPainter *painter, 63 | const QStyleOptionViewItem &option, 64 | const QModelIndex &index, bool checked) const = 0; 65 | }; 66 | 67 | class RadioIndicatorMenuItemDelegate : public CheckableMenuItemDelegate 68 | { 69 | Q_OBJECT 70 | 71 | public: 72 | explicit RadioIndicatorMenuItemDelegate(QObject *parent = nullptr); 73 | 74 | protected: 75 | void drawIndicator(QPainter *painter, 76 | const QStyleOptionViewItem &option, 77 | const QModelIndex &index, bool checked) const override; 78 | }; 79 | 80 | class CheckIndicatorMenuItemDelegate : public CheckableMenuItemDelegate 81 | { 82 | Q_OBJECT 83 | 84 | public: 85 | explicit CheckIndicatorMenuItemDelegate(QObject *parent = nullptr); 86 | 87 | protected: 88 | void drawIndicator(QPainter *painter, 89 | const QStyleOptionViewItem &option, 90 | const QModelIndex &index, bool checked) const override; 91 | }; 92 | -------------------------------------------------------------------------------- /src/GalleryInterface.h: -------------------------------------------------------------------------------- 1 | #ifndef GALLERY_INTERFACE_H 2 | #define GALLERY_INTERFACE_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | #include "QFluent/ScrollArea.h" 18 | #include "QFluent/PushButton.h" 19 | #include "QFluent/ToolButton.h" 20 | #include "QFluent/IconWidget.h" 21 | #include "QFluent/Label.h" 22 | 23 | 24 | class SeparatorWidget : public QWidget 25 | { 26 | Q_OBJECT 27 | 28 | public: 29 | explicit SeparatorWidget(QWidget *parent = nullptr); 30 | 31 | protected: 32 | void paintEvent(QPaintEvent *e) override; 33 | }; 34 | 35 | class ToolBar : public QWidget 36 | { 37 | Q_OBJECT 38 | 39 | public: 40 | ToolBar(const QString &title, const QString &subtitle, QWidget *parent = nullptr); 41 | 42 | private slots: 43 | void initWidget(); 44 | 45 | private: 46 | TitleLabel *titleLabel; 47 | CaptionLabel *subtitleLabel; 48 | PushButton *documentButton; 49 | PushButton *sourceButton; 50 | ToolButton *themeButton; 51 | SeparatorWidget *separator; 52 | ToolButton *supportButton; 53 | ToolButton *feedbackButton; 54 | QVBoxLayout *vBoxLayout; 55 | QHBoxLayout *buttonLayout; 56 | }; 57 | 58 | class ExampleCard : public QWidget 59 | { 60 | Q_OBJECT 61 | 62 | public: 63 | ExampleCard(const QString &title, QWidget *widget, const QString &sourcePath, 64 | int stretch = 0, QWidget *parent = nullptr); 65 | 66 | protected: 67 | bool eventFilter(QObject *obj, QEvent *e) override; 68 | 69 | private: 70 | void initWidget(); 71 | void initLayout(); 72 | 73 | QWidget *widget; 74 | int stretch; 75 | StrongBodyLabel *titleLabel; 76 | QFrame *card; 77 | QFrame *sourceWidget; 78 | QString sourcePath; 79 | BodyLabel *sourcePathLabel; 80 | IconWidget *linkIcon; 81 | QVBoxLayout *vBoxLayout; 82 | QVBoxLayout *cardLayout; 83 | QHBoxLayout *topLayout; 84 | QHBoxLayout *bottomLayout; 85 | }; 86 | 87 | class GalleryInterface : public ScrollArea 88 | { 89 | Q_OBJECT 90 | 91 | public: 92 | GalleryInterface(const QString &title, const QString &subtitle, QWidget *parent = nullptr); 93 | 94 | ExampleCard* addExampleCard(const QString &title, QWidget *widget, const QString &sourcePath = "", int stretch = 0); 95 | void scrollToCard(int index); 96 | 97 | QLayout *layout() const; 98 | 99 | protected: 100 | void resizeEvent(QResizeEvent *e) override; 101 | 102 | private: 103 | QWidget *view; 104 | ToolBar *toolBar; 105 | QVBoxLayout *vBoxLayout; 106 | }; 107 | 108 | #endif // GALLERY_INTERFACE_H 109 | -------------------------------------------------------------------------------- /src/NavigationViewInterface.cpp: -------------------------------------------------------------------------------- 1 | #include "NavigationViewInterface.h" 2 | 3 | #include "FluentIcon.h" 4 | #include "QFluent/Label.h" 5 | #include "QFluent/SpinBox.h" 6 | #include "QFluent/CheckBox.h" 7 | #include "QFluent/ComboBox.h" 8 | #include "QFluent/navigation/Pivot.h" 9 | 10 | NavigationViewInterface::NavigationViewInterface(QWidget *parent) 11 | : GalleryInterface("导航", "", parent) 12 | { 13 | setObjectName("NavigationViewInterface"); 14 | 15 | auto pivot = new Pivot(this); 16 | pivot->addItem("1", "主页", FluentIcon(Fluent::IconType::HOME)); 17 | pivot->addItem("2", "订阅", FluentIcon(Fluent::IconType::BOOK_SHELF)); 18 | pivot->addItem("3", "历史", FluentIcon(Fluent::IconType::HISTORY)); 19 | pivot->addItem("4", "设置", FluentIcon(Fluent::IconType::SETTING)); 20 | 21 | addExampleCard("顶部导航栏", pivot); 22 | 23 | addExampleCard("标签导航", createTabWidget(), "", 1); 24 | } 25 | 26 | QWidget* NavigationViewInterface::createTabWidget() 27 | { 28 | auto tabView = new QWidget(this); 29 | tabView->setMinimumHeight(200); 30 | 31 | stacked = new StackedWidget(tabView); 32 | stacked->setStyleSheet(R"( 33 | StackedWidget { 34 | border-right: none; 35 | border-bottom: none; 36 | border-top-left-radius: 10px; 37 | background-color: transparent; 38 | border: none; 39 | } 40 | )"); 41 | 42 | tabBar = new TabBar(tabView); 43 | tabBar->setMovable(true); // 禁用拖拽标签 44 | tabBar->setTabsClosable(true); // 显示关闭按钮 45 | tabBar->setAddButtonVisible(true); // 显示添加按钮 46 | tabBar->setScrollable(false); // 禁用标签滚动 47 | tabBar->setTabShadowEnabled(true); // 启用标签阴影 48 | 49 | addTab(); 50 | addTab(); 51 | 52 | auto vBoxLayout = new QVBoxLayout(tabView); 53 | vBoxLayout->setContentsMargins(0, 0, 0, 0); 54 | 55 | vBoxLayout->addWidget(tabBar); 56 | vBoxLayout->addWidget(stacked); 57 | 58 | connect(tabBar, &TabBar::tabAddRequested, this, [=](){ addTab(); }); 59 | connect(tabBar, &TabBar::tabCloseRequested, this, [=](int index){ removeTab(index); }); 60 | connect(tabBar, &TabBar::tabBarClicked, this, [=](int index){ 61 | int key = tabBar->tabItem(index)->routeKey().toInt(); 62 | stacked->setCurrentWidget(tabMap.value(key)); 63 | }); 64 | 65 | return tabView; 66 | } 67 | 68 | void NavigationViewInterface::addTab() 69 | { 70 | int count = ++tabCount; 71 | tabBar->addTab(QString::number(count), QString("新建标签x%1").arg(count), QIcon(":/res/example.png")); 72 | 73 | auto label = new TitleLabel(QString("标签页x%1").arg(count), stacked); 74 | label->setAlignment(Qt::AlignCenter); 75 | stacked->addWidget(label); 76 | tabMap.insert(count, label); 77 | } 78 | 79 | void NavigationViewInterface::removeTab(int index) 80 | { 81 | int key = tabBar->tabItem(index)->routeKey().toInt(); 82 | stacked->removeWidget(tabMap.value(key)); 83 | tabBar->removeTab(index); 84 | } 85 | -------------------------------------------------------------------------------- /src/Window/NavbarWindow.cpp: -------------------------------------------------------------------------------- 1 | #include "NavbarWindow.h" 2 | 3 | #include 4 | 5 | #include "StyleSheet.h" 6 | #include "QFluent/Label.h" 7 | #include "QFluent/StackedWidget.h" 8 | #include "QFluent/navigation/NavigationBar.h" 9 | 10 | NavbarWidget::NavbarWidget() 11 | { 12 | setWindowButtonHints(Fluent::WindowButtonHint::Icon | Fluent::WindowButtonHint::Title | 13 | Fluent::WindowButtonHint::Minimize | Fluent::WindowButtonHint::Maximize | 14 | Fluent::WindowButtonHint::Close); 15 | 16 | setContentsMargins(0, 0, 0, 0); 17 | 18 | resize(800, 600); 19 | 20 | initUI(); 21 | } 22 | 23 | void NavbarWidget::initUI() 24 | { 25 | setWindowTitle("QFluentKit"); 26 | setWindowIcon(QPixmap(":/res/example.png")); 27 | 28 | auto w = new QWidget(this); 29 | setCentralWidget(w); 30 | 31 | auto hBoxLayout = new QHBoxLayout(w); 32 | hBoxLayout->setSpacing(0); 33 | hBoxLayout->setContentsMargins(0, 0, 0, 0); 34 | 35 | auto stacked = new StackedWidget(this); 36 | stacked->addWidget(createWidget("主页", stacked)); 37 | stacked->addWidget(createWidget("输入", stacked)); 38 | stacked->addWidget(createWidget("日期", stacked)); 39 | stacked->addWidget(createWidget("信息框", stacked)); 40 | stacked->addWidget(createWidget("设置", stacked)); 41 | 42 | StyleSheetManager::instance()->registerWidget(stacked, Fluent::ThemeStyle::FLUENT_WINDOW); 43 | 44 | 45 | auto *navigationBar = new NavigationBar(this); 46 | navigationBar->addItem("1", FluentIcon(Fluent::IconType::HOME), "主页", [stacked](){stacked->setCurrentIndex(0, false);}, true, Fluent::NavigationItemPosition::TOP); 47 | navigationBar->addSeparator(); 48 | navigationBar->addItem("2", FluentIcon(Fluent::IconType::CHECKBOX), "输入", [stacked](){stacked->setCurrentIndex(1, false);}, true, Fluent::NavigationItemPosition::SCROLL); 49 | navigationBar->addItem("3", FluentIcon(Fluent::IconType::DATE_TIME), "日期", [stacked](){stacked->setCurrentIndex(2, false);}, true, Fluent::NavigationItemPosition::SCROLL); 50 | navigationBar->addItem("4", FluentIcon(Fluent::IconType::MESSAGE), "信息框", [stacked](){stacked->setCurrentIndex(3, false);}, true, Fluent::NavigationItemPosition::SCROLL); 51 | navigationBar->addSeparator(Fluent::NavigationItemPosition::BOTTOM); 52 | navigationBar->addItem("5", FluentIcon(Fluent::IconType::SETTING), "设置", [stacked](){stacked->setCurrentIndex(4, false);}, true, Fluent::NavigationItemPosition::BOTTOM); 53 | navigationBar->setCurrentItem("1"); 54 | 55 | 56 | hBoxLayout->addWidget(navigationBar, 0); 57 | hBoxLayout->addWidget(stacked, 1); 58 | } 59 | 60 | QWidget* NavbarWidget::createWidget(const QString &text, QWidget* parent) 61 | { 62 | auto w = new QWidget(parent); 63 | auto hLay = new QHBoxLayout(w); 64 | auto label = new DisplayLabel(text, w); 65 | label->setAlignment(Qt::AlignCenter); 66 | hLay->addWidget(label); 67 | return w; 68 | } 69 | -------------------------------------------------------------------------------- /src/ConfigManager.h: -------------------------------------------------------------------------------- 1 | #ifndef CONFIGMANAGER_H 2 | #define CONFIGMANAGER_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | class ConfigManager 12 | { 13 | public: 14 | // 获取单例实例 15 | static ConfigManager& instance(); 16 | 17 | // 读取配置值,如果不存在则返回默认值 18 | QVariant getValue(const QString& key, const QVariant& defaultValue = QVariant()) const 19 | { 20 | return m_settings.value(key, defaultValue); 21 | } 22 | 23 | // 设置配置值 24 | void setValue(const QString& key, const QVariant& value) 25 | { 26 | m_settings.setValue(key, value); 27 | } 28 | 29 | // 同步配置到文件 30 | void sync() 31 | { 32 | m_settings.sync(); 33 | } 34 | 35 | // 检查键是否存在 36 | bool contains(const QString& key) const 37 | { 38 | return m_settings.contains(key); 39 | } 40 | 41 | // 移除配置项 42 | void remove(const QString& key) 43 | { 44 | m_settings.remove(key); 45 | } 46 | 47 | // 获取所有子键 48 | QStringList allKeys() const 49 | { 50 | return m_settings.allKeys(); 51 | } 52 | 53 | // 获取所有子组 54 | QStringList childGroups() const 55 | { 56 | return m_settings.childGroups(); 57 | } 58 | 59 | 60 | bool isWin11() 61 | { 62 | #if defined(Q_OS_WIN) 63 | // 方法1:通过注册表读取 CurrentBuild(推荐,简单可靠) 64 | QSettings reg(R"(HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion)", 65 | QSettings::NativeFormat); 66 | bool ok = false; 67 | int buildNumber = reg.value("CurrentBuild").toInt(&ok); 68 | 69 | if (ok && buildNumber >= 22000) { 70 | return true; 71 | } 72 | 73 | // 备用:尝试用 QOperatingSystemVersion(Qt5.9+ 支持,但 Win11 可能被报告为 Win10) 74 | // 注意:Qt5 中 QOperatingSystemVersion::Windows10 实际包含 Win11 75 | auto current = QOperatingSystemVersion::current(); 76 | if (current.type() == QOperatingSystemVersion::Windows) { 77 | // Qt6 开始提供 build(),Qt5 没有 78 | #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) 79 | return current.microVersion() >= 22000; // microVersion() = build number in Qt6 80 | #else 81 | // Qt5 无法直接获取 build,只能依赖注册表(上面已处理) 82 | return false; 83 | #endif 84 | } 85 | #endif 86 | 87 | // 非 Windows 系统 88 | return false; 89 | } 90 | 91 | private: 92 | ConfigManager() 93 | : m_settings("config.ini", QSettings::IniFormat) 94 | { 95 | 96 | } 97 | 98 | ~ConfigManager() 99 | { 100 | m_settings.sync(); 101 | } 102 | 103 | QSettings m_settings; 104 | }; 105 | 106 | inline ConfigManager& ConfigManager::instance() 107 | { 108 | static ConfigManager instance; 109 | return instance; 110 | } 111 | 112 | #endif // CONFIGMANAGER_H 113 | -------------------------------------------------------------------------------- /src/Card/LinkCard.cpp: -------------------------------------------------------------------------------- 1 | #include "LinkCard.h" 2 | #include "QFluent/IconWidget.h" 3 | #include "TextWrap.h" 4 | #include "FluentGlobal.h" 5 | #include 6 | #include 7 | 8 | #include "StyleSheet.h" 9 | 10 | LinkCard::LinkCard(const QIcon &icon, const QString &title, const QString &content, 11 | const QString &url, QWidget *parent) 12 | : QFrame(parent) 13 | , m_url(url) 14 | { 15 | m_iconWidget = new IconWidget(icon, this); 16 | m_titleLabel = new QLabel(title, this); 17 | m_contentLabel = new QLabel(TextWrap::wrap(content, 28, false).first, this); 18 | m_urlWidget = new IconWidget(FluentIcon(Fluent::IconType::LINK), this); // 需要链接图标 19 | 20 | initWidget(); 21 | } 22 | 23 | void LinkCard::initWidget() 24 | { 25 | setCursor(Qt::PointingHandCursor); 26 | setFixedSize(198, 220); 27 | 28 | m_iconWidget->setFixedSize(54, 54); 29 | m_urlWidget->setFixedSize(16, 16); 30 | 31 | QVBoxLayout *vBoxLayout = new QVBoxLayout(this); 32 | vBoxLayout->setSpacing(0); 33 | vBoxLayout->setContentsMargins(24, 24, 0, 13); 34 | vBoxLayout->addWidget(m_iconWidget); 35 | vBoxLayout->addSpacing(16); 36 | vBoxLayout->addWidget(m_titleLabel); 37 | vBoxLayout->addSpacing(8); 38 | vBoxLayout->addWidget(m_contentLabel); 39 | vBoxLayout->setAlignment(Qt::AlignLeft | Qt::AlignTop); 40 | 41 | // 手动设置URL小部件位置 42 | m_urlWidget->move(170, 192); 43 | 44 | m_titleLabel->setObjectName("titleLabel"); 45 | m_contentLabel->setObjectName("contentLabel"); 46 | 47 | } 48 | 49 | void LinkCard::mouseReleaseEvent(QMouseEvent *event) 50 | { 51 | QFrame::mouseReleaseEvent(event); 52 | QDesktopServices::openUrl(m_url); 53 | } 54 | 55 | LinkCardView::LinkCardView(QWidget *parent) 56 | : ScrollArea(parent) 57 | { 58 | m_view = new QWidget(this); 59 | m_hBoxLayout = new QHBoxLayout(m_view); 60 | 61 | initWidget(); 62 | } 63 | 64 | void LinkCardView::initWidget() 65 | { 66 | m_hBoxLayout->setContentsMargins(36, 0, 0, 0); 67 | m_hBoxLayout->setSpacing(12); 68 | m_hBoxLayout->setAlignment(Qt::AlignLeft); 69 | 70 | setWidget(m_view); 71 | setWidgetResizable(true); 72 | setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); 73 | setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); 74 | 75 | m_view->setObjectName("view"); 76 | 77 | auto styleSource = std::make_shared(":/res/style/{theme}/link_card.qss"); 78 | StyleSheetManager::instance()->registerWidget(styleSource, this); 79 | 80 | } 81 | 82 | void LinkCardView::addCard(const QIcon &icon, const QString &title, const QString &content, const QString &url) 83 | { 84 | LinkCard *card = new LinkCard(icon, title, content, url, m_view); 85 | m_hBoxLayout->addWidget(card, 0, Qt::AlignLeft); 86 | } 87 | 88 | void LinkCardView::addCard(const QString &iconPath, const QString &title, const QString &content, const QString &url) 89 | { 90 | addCard(QIcon(iconPath), title, content, url); 91 | } 92 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.5) 2 | project(QFluentExample LANGUAGES CXX) 3 | 4 | # 支持Qt5和Qt6 5 | find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core) 6 | find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core Widgets Svg Xml) 7 | 8 | set(CMAKE_AUTOMOC ON) 9 | set(CMAKE_AUTORCC ON) 10 | set(CMAKE_AUTOUIC ON) 11 | 12 | add_compile_options("$<$:/utf-8>") 13 | 14 | include_directories(${CMAKE_CURRENT_SOURCE_DIR}/libs/include) 15 | 16 | file(GLOB_RECURSE SOURCES 17 | CONFIGURE_DEPENDS 18 | RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} 19 | src/*.cpp 20 | src/*.h 21 | ) 22 | set(CPP_SOURCES "") 23 | set(HEADER_SOURCES "") 24 | foreach(file ${SOURCES}) 25 | if(file MATCHES "\\.cpp$") 26 | list(APPEND CPP_SOURCES ${file}) 27 | elseif(file MATCHES "\\.h$") 28 | list(APPEND HEADER_SOURCES ${file}) 29 | endif() 30 | endforeach() 31 | 32 | file(GLOB_RECURSE AUTO_RESOURCE_FILES 33 | RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} 34 | res/*.png res/*.jpg res/*.jpeg res/*.gif res/*.svg res/*.ico res/*.ttf res/*.qss 35 | ) 36 | 37 | # 资源处理:兼容Qt5和Qt6 38 | if(${QT_VERSION_MAJOR} EQUAL 6) 39 | add_executable(QFluentExample 40 | WIN32 MACOSX_BUNDLE 41 | ${CPP_SOURCES} 42 | ${HEADER_SOURCES} 43 | version.rc 44 | ) 45 | qt_add_resources(QFluentExample "QFluentExample" 46 | PREFIX "/" 47 | FILES ${AUTO_RESOURCE_FILES} 48 | ) 49 | else() 50 | # 对于Qt5,需要生成RCC源文件 51 | add_executable(QFluentExample 52 | WIN32 MACOSX_BUNDLE 53 | ${CPP_SOURCES} 54 | ${HEADER_SOURCES} 55 | version.rc 56 | res/res.qrc 57 | ) 58 | endif() 59 | 60 | 61 | 62 | # 初始化变量 63 | unset(QT_VERSION_STRING) 64 | 65 | if(TARGET Qt6::Core) 66 | set(QT_MAJOR_VERSION "6") 67 | set(QT_VERSION_STRING ${Qt6_VERSION}) 68 | elseif(TARGET Qt5::Core) 69 | set(QT_MAJOR_VERSION "5") 70 | # Qt5 每个模块有自己的版本变量,Core 是基础 71 | set(QT_VERSION_STRING ${Qt5Core_VERSION}) 72 | else() 73 | message(FATAL_ERROR "Neither Qt5 nor Qt6 found! Please install Qt and set CMAKE_PREFIX_PATH.") 74 | endif() 75 | 76 | # 获取编译器信息 77 | set(COMPILER_INFO ${CMAKE_CXX_COMPILER_ID}) 78 | 79 | # 拼接最终字符串 80 | set(QT_AND_COMPILER_STRING "${QT_VERSION_STRING}_${COMPILER_INFO}") 81 | 82 | # 输出 83 | message(STATUS "Detected build environment: ${QT_AND_COMPILER_STRING}") 84 | 85 | 86 | set(SDK_DIR "${CMAKE_CURRENT_SOURCE_DIR}/libs/${QT_AND_COMPILER_STRING}") 87 | 88 | message(STATUS "SDK Path:: ${SDK_DIR}") 89 | 90 | add_custom_command(TARGET QFluentExample POST_BUILD 91 | COMMAND ${CMAKE_COMMAND} -E copy_directory 92 | ${SDK_DIR}/bin/$ 93 | $ 94 | COMMENT "Copying DLLs from ${SDK_DIR}" 95 | ) 96 | 97 | target_link_libraries(QFluentExample PRIVATE 98 | $<$:${SDK_DIR}/lib/Debug/QFluent.lib> 99 | $<$:${SDK_DIR}/lib/Release/QFluent.lib> 100 | ) 101 | 102 | target_link_libraries(QFluentExample 103 | PRIVATE 104 | Qt${QT_VERSION_MAJOR}::Core 105 | Qt${QT_VERSION_MAJOR}::Widgets 106 | Qt${QT_VERSION_MAJOR}::Svg 107 | Qt${QT_VERSION_MAJOR}::Xml 108 | ) 109 | include(GNUInstallDirs) 110 | install(TARGETS QFluentExample 111 | BUNDLE DESTINATION . 112 | RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} 113 | LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} 114 | ) 115 | -------------------------------------------------------------------------------- /libs/include/QFluent/PagiNation.h: -------------------------------------------------------------------------------- 1 | #ifndef PAGINATION_H 2 | #define PAGINATION_H 3 | 4 | #include 5 | #include "FluentGlobal.h" 6 | #include "PushButton.h" 7 | 8 | using namespace std; 9 | 10 | struct __PagiNation_DATA { 11 | int type; // 1: 按钮 2: 点 12 | int labelNum; 13 | bool choosed; 14 | }; 15 | 16 | class QFLUENT_EXPORT Button: public TransparentTogglePushButton { 17 | Q_OBJECT 18 | public: 19 | explicit Button(const QString& text, QWidget *parent = nullptr); 20 | 21 | signals: 22 | void cClick(Button*); 23 | 24 | private slots: 25 | void handleClick(); 26 | }; 27 | 28 | class QHBoxLayout; 29 | class QSpacerItem; 30 | class TransparentToolButton; 31 | class QFLUENT_EXPORT PagiNation: public QFrame { 32 | Q_OBJECT 33 | public: 34 | PagiNation (QWidget *parent, Fluent::Alignment align = Fluent::Alignment::Align_Right, int buttonCount = 7); 35 | PagiNation (QPoint point, QWidget *parent, Fluent::Alignment align = Fluent::Alignment::Align_Right, int buttonCount = 7); 36 | PagiNation (QSize size, QWidget *parent, Fluent::Alignment align = Fluent::Alignment::Align_Right, int buttonCount = 7); 37 | PagiNation (QRect rect, QWidget *parent, Fluent::Alignment align = Fluent::Alignment::Align_Right, int buttonCount = 7); 38 | 39 | private: 40 | Fluent::Alignment _align; 41 | int _buttonCount; 42 | int _height; 43 | QHBoxLayout *BJ, *BJ_main; 44 | QSpacerItem *TH_left, *TH_right; 45 | int _pageNow = 1, _total = 0, _pageSize = 10; 46 | TransparentToolButton *prevBtn, *nextBtn, *prevFBtn, *nextFBtn; 47 | QFrame *mainBox; 48 | 49 | signals: 50 | /** 页码变更信号 */ 51 | void pageChanged (int pageNow, int pageSize); 52 | 53 | public: 54 | /** 获取当前页码 page */ 55 | int page (); 56 | /** 获取当前每页条数 pagesize */ 57 | int pageSize (); 58 | /** 获取当前数据总条数 pagesize */ 59 | int total (); 60 | /** 获取当前最大按钮数 pagesize */ 61 | int buttonCount (); 62 | /** 获取当前对齐方式 pagesize */ 63 | Fluent::Alignment alignment (); 64 | /** 设置最大按钮数量 */ 65 | void setButtonCount (int buttonCount, bool needEmit = false); 66 | /** 设置左右对齐方式 */ 67 | void setAlign (Fluent::Alignment align, bool needEmit = false); 68 | /** 设置每页条数 */ 69 | void setPageSize (int pageSize, bool needEmit = false); 70 | /** 设置总条数(用于计算总页数) */ 71 | void setTotal (int total, bool needEmit = false); 72 | /** 设置页码 */ 73 | void setPage (int pageNow, bool needEmit = false); 74 | /** 设置页码 */ 75 | void setPage (int pageNow, int total, bool needEmit = false); 76 | /** 连接 "页码变更" 信号 */ 77 | void connectPageChange (function method); 78 | /** 连接 "页码变更" 信号 */ 79 | void connectPageChange (function method); 80 | /** 连接 "页码变更" 信号 */ 81 | void connectPageChange (function method); 82 | 83 | private: 84 | void init (); 85 | /** 计算当前页码展示 */ 86 | void computePage (); 87 | /** 渲染按钮列表 */ 88 | void renderBtn (QList<__PagiNation_DATA> list); 89 | /** 设置控件对齐 */ 90 | void setWidgetAlign (); 91 | 92 | private slots: 93 | /** 点击页码按钮 槽函数 */ 94 | void handleClick (Button *self); 95 | /** 页码后退1 */ 96 | void toPrev1 (); 97 | /** 页码后退5 */ 98 | void toPrev5 (); 99 | /** 页码前进1 */ 100 | void toNext1 (); 101 | /** 页码前进5 */ 102 | void toNext5 (); 103 | }; 104 | 105 | #endif // PAGINATION_H 106 | -------------------------------------------------------------------------------- /libs/include/QFluent/AvatarWidget.h: -------------------------------------------------------------------------------- 1 | #ifndef IMAGELABEL_H 2 | #define IMAGELABEL_H 3 | 4 | #include 5 | 6 | class ImageLabel : public QLabel 7 | { 8 | Q_OBJECT 9 | Q_PROPERTY(int topLeftRadius READ topLeftRadius WRITE setTopLeftRadius) 10 | Q_PROPERTY(int topRightRadius READ topRightRadius WRITE setTopRightRadius) 11 | Q_PROPERTY(int bottomLeftRadius READ bottomLeftRadius WRITE setBottomLeftRadius) 12 | Q_PROPERTY(int bottomRightRadius READ bottomRightRadius WRITE setBottomRightRadius) 13 | 14 | public: 15 | explicit ImageLabel(QWidget *parent = nullptr); 16 | ImageLabel(const QString &image, QWidget *parent = nullptr); 17 | ImageLabel(const QImage &image, QWidget *parent = nullptr); 18 | ImageLabel(const QPixmap &image, QWidget *parent = nullptr); 19 | 20 | void setBorderRadius(int topLeft, int topRight, int bottomLeft, int bottomRight); 21 | 22 | void scaledToWidth(int width); 23 | void scaledToHeight(int height); 24 | void setScaledSize(const QSize &size); 25 | bool isNull() const; 26 | QPixmap pixmap() const; 27 | void setMovie(QMovie *movie); 28 | 29 | int topLeftRadius() const; 30 | void setTopLeftRadius(int radius); 31 | 32 | int topRightRadius() const; 33 | void setTopRightRadius(int radius); 34 | 35 | int bottomLeftRadius() const; 36 | void setBottomLeftRadius(int radius); 37 | 38 | int bottomRightRadius() const; 39 | void setBottomRightRadius(int radius); 40 | 41 | QImage image() const; 42 | void setImage(const QVariant &image); 43 | 44 | signals: 45 | void clicked(); 46 | 47 | protected: 48 | void mouseReleaseEvent(QMouseEvent *event) override; 49 | void paintEvent(QPaintEvent *event) override; 50 | 51 | private slots: 52 | void _onFrameChanged(int frameNumber); 53 | 54 | private: 55 | void _postInit(); 56 | 57 | QImage m_image; 58 | int m_topLeftRadius; 59 | int m_topRightRadius; 60 | int m_bottomLeftRadius; 61 | int m_bottomRightRadius; 62 | }; 63 | 64 | class AvatarWidget : public ImageLabel 65 | { 66 | Q_OBJECT 67 | Q_PROPERTY(int radius READ radius WRITE setRadius) 68 | Q_PROPERTY(QColor lightBackgroundColor READ lightBackgroundColor WRITE setLightBackgroundColor) 69 | Q_PROPERTY(QColor darkBackgroundColor READ darkBackgroundColor WRITE setDarkBackgroundColor) 70 | 71 | public: 72 | explicit AvatarWidget(QWidget *parent = nullptr); 73 | AvatarWidget(const QString &image, QWidget *parent = nullptr); 74 | AvatarWidget(const QImage &image, QWidget *parent = nullptr); 75 | AvatarWidget(const QPixmap &image, QWidget *parent = nullptr); 76 | 77 | int radius() const; 78 | void setRadius(int radius); 79 | 80 | QColor lightBackgroundColor() const; 81 | void setLightBackgroundColor(const QColor &color); 82 | 83 | QColor darkBackgroundColor() const; 84 | void setDarkBackgroundColor(const QColor &color); 85 | 86 | void setBackgroundColor(const QColor &light, const QColor &dark); 87 | void setImage(const QVariant &image); 88 | 89 | protected: 90 | void paintEvent(QPaintEvent *event) override; 91 | 92 | private: 93 | void _drawImageAvatar(QPainter &painter); 94 | void _drawTextAvatar(QPainter &painter); 95 | 96 | int m_radius; 97 | QColor m_lightBackgroundColor; 98 | QColor m_darkBackgroundColor; 99 | }; 100 | 101 | #endif // IMAGELABEL_H 102 | -------------------------------------------------------------------------------- /libs/include/QFluent/StackedWidget.h: -------------------------------------------------------------------------------- 1 | #ifndef STACKEDWIDGET_H 2 | #define STACKEDWIDGET_H 3 | 4 | #include 5 | #include 6 | 7 | #include "FluentGlobal.h" 8 | 9 | QT_BEGIN_NAMESPACE 10 | class QPropertyAnimation; 11 | QT_END_NAMESPACE 12 | 13 | class QHBoxLayout; 14 | class QGraphicsOpacityEffect; 15 | class OpacityAniStackedWidget : public QStackedWidget 16 | { 17 | Q_OBJECT 18 | 19 | public: 20 | explicit OpacityAniStackedWidget(QWidget *parent = nullptr); 21 | 22 | void addWidget(QWidget *w); 23 | void setCurrentIndex(int index); 24 | void setCurrentWidget(QWidget *w); 25 | 26 | private slots: 27 | void __onAniFinished(); 28 | 29 | private: 30 | int __nextIndex; 31 | QList __effects; 32 | QList __anis; 33 | }; 34 | 35 | 36 | // ============ PopUpAniInfo ============ 37 | struct PopUpAniInfo 38 | { 39 | QWidget *widget; 40 | int deltaX; 41 | int deltaY; 42 | QPropertyAnimation *ani; 43 | 44 | PopUpAniInfo(QWidget *w, int dx, int dy, QPropertyAnimation *a) 45 | : widget(w), deltaX(dx), deltaY(dy), ani(a) {} 46 | }; 47 | 48 | 49 | // ============ PopUpAniStackedWidget ============ 50 | class PopUpAniStackedWidget : public QStackedWidget 51 | { 52 | Q_OBJECT 53 | 54 | public: 55 | explicit PopUpAniStackedWidget(QWidget *parent = nullptr); 56 | 57 | void addWidget(QWidget *widget, int deltaX = 0, int deltaY = 76); 58 | void removeWidget(QWidget *widget); 59 | 60 | void setAnimationEnabled(bool isEnabled); 61 | bool isAnimationEnabled() const { return m_isAnimationEnabled; } 62 | 63 | void setCurrentIndex(int index, bool needPopOut = false, bool showNextWidgetDirectly = true, 64 | int duration = 250, QEasingCurve easingCurve = QEasingCurve::OutQuad); 65 | void setCurrentWidget(QWidget *widget, bool needPopOut = false, bool showNextWidgetDirectly = true, 66 | int duration = 250, QEasingCurve easingCurve = QEasingCurve::OutQuad); 67 | 68 | signals: 69 | void aniFinished(); 70 | void aniStart(); 71 | 72 | private: 73 | void __setAnimation(QPropertyAnimation *ani, const QPoint &startValue, const QPoint &endValue, 74 | int duration, QEasingCurve easingCurve = QEasingCurve::Linear); 75 | void __onAniFinished(); 76 | 77 | QList m_aniInfos; 78 | bool m_isAnimationEnabled; 79 | int m_nextIndex; 80 | QPropertyAnimation *m_ani; 81 | }; 82 | 83 | 84 | // ============ 最终暴露的 StackedWidget ============ 85 | class QFLUENT_EXPORT StackedWidget : public QFrame 86 | { 87 | Q_OBJECT 88 | 89 | public: 90 | explicit StackedWidget(QWidget *parent = nullptr); 91 | 92 | bool isAnimationEnabled() const; 93 | void setAnimationEnabled(bool isEnabled); 94 | 95 | void addWidget(QWidget *widget); 96 | void removeWidget(QWidget *widget); 97 | QWidget* widget(int index) const; 98 | void setCurrentWidget(QWidget *widget, bool popOut = true); 99 | void setCurrentIndex(int index, bool popOut = true); 100 | int currentIndex() const; 101 | QWidget* currentWidget() const; 102 | int indexOf(QWidget *widget) const; 103 | int count() const; 104 | 105 | signals: 106 | void currentChanged(int index); 107 | 108 | private: 109 | QHBoxLayout *hBoxLayout; 110 | PopUpAniStackedWidget *view; 111 | }; 112 | 113 | #endif // STACKEDWIDGET_H 114 | -------------------------------------------------------------------------------- /src/Card/SampleCard.cpp: -------------------------------------------------------------------------------- 1 | #include "SampleCard.h" 2 | #include "QFluent/IconWidget.h" 3 | #include "TextWrap.h" 4 | #include 5 | #include "StyleSheet.h" 6 | 7 | SampleCard::SampleCard(const QIcon &icon, const QString &title, const QString &content, 8 | const QString &routeKey, int index, QWidget *parent) 9 | : CardWidget(parent) 10 | , m_index(index) 11 | , m_routeKey(routeKey) 12 | { 13 | m_iconWidget = new IconWidget(icon, this); 14 | m_titleLabel = new QLabel(title, this); 15 | m_contentLabel = new QLabel(TextWrap::wrap(content, 45, false).first, this); 16 | 17 | initWidget(); 18 | } 19 | 20 | void SampleCard::initWidget() 21 | { 22 | setCursor(Qt::PointingHandCursor); 23 | setFixedSize(360, 90); 24 | 25 | m_iconWidget->setFixedSize(48, 48); 26 | 27 | QHBoxLayout *hBoxLayout = new QHBoxLayout(this); 28 | QVBoxLayout *vBoxLayout = new QVBoxLayout(); 29 | 30 | hBoxLayout->setSpacing(28); 31 | hBoxLayout->setContentsMargins(20, 0, 0, 0); 32 | vBoxLayout->setSpacing(2); 33 | vBoxLayout->setContentsMargins(0, 0, 0, 0); 34 | vBoxLayout->setAlignment(Qt::AlignVCenter); 35 | 36 | hBoxLayout->setAlignment(Qt::AlignVCenter); 37 | hBoxLayout->addWidget(m_iconWidget); 38 | hBoxLayout->addLayout(vBoxLayout); 39 | vBoxLayout->addStretch(1); 40 | vBoxLayout->addWidget(m_titleLabel); 41 | vBoxLayout->addWidget(m_contentLabel); 42 | vBoxLayout->addStretch(1); 43 | 44 | m_titleLabel->setObjectName("titleLabel"); 45 | m_contentLabel->setObjectName("contentLabel"); 46 | } 47 | 48 | void SampleCard::mouseReleaseEvent(QMouseEvent *event) 49 | { 50 | CardWidget::mouseReleaseEvent(event); 51 | emit clicked(m_routeKey, m_index); 52 | } 53 | 54 | SampleCardView::SampleCardView(const QString &title, QWidget *parent) 55 | : QWidget(parent) 56 | , m_flowLayout(nullptr) 57 | { 58 | m_titleLabel = new QLabel(title, this); 59 | m_vBoxLayout = new QVBoxLayout(this); 60 | 61 | initWidget(); 62 | createFlowLayout(); 63 | } 64 | 65 | void SampleCardView::initWidget() 66 | { 67 | m_vBoxLayout->setContentsMargins(36, 0, 36, 0); 68 | m_vBoxLayout->setSpacing(10); 69 | 70 | m_vBoxLayout->addWidget(m_titleLabel); 71 | 72 | m_titleLabel->setObjectName("viewTitleLabel"); 73 | 74 | auto styleSource = std::make_shared(":/res/style/{theme}/sample_card.qss"); 75 | StyleSheetManager::instance()->registerWidget(styleSource, this); 76 | } 77 | 78 | void SampleCardView::createFlowLayout() 79 | { 80 | m_flowLayout = new FlowLayout(); 81 | m_flowLayout->setContentsMargins(0, 0, 0, 0); 82 | m_flowLayout->setHorizontalSpacing(12); 83 | m_flowLayout->setVerticalSpacing(12); 84 | 85 | m_vBoxLayout->addLayout(m_flowLayout); 86 | } 87 | 88 | void SampleCardView::addSampleCard(const QIcon &icon, const QString &title, 89 | const QString &content, const QString &routeKey, int index) 90 | { 91 | SampleCard *card = new SampleCard(icon, title, content, routeKey, index, this); 92 | m_flowLayout->addWidget(card); 93 | 94 | connect(card, &SampleCard::clicked, this, &SampleCardView::clicked); 95 | } 96 | 97 | void SampleCardView::addSampleCard(const QString &iconPath, const QString &title, 98 | const QString &content, const QString &routeKey, int index) 99 | { 100 | addSampleCard(QIcon(iconPath), title, content, routeKey, index); 101 | } 102 | -------------------------------------------------------------------------------- /res/icons/Price_black.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /res/icons/Price_white.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /libs/include/QFluent/Slider.h: -------------------------------------------------------------------------------- 1 | #ifndef SLIDER_H 2 | #define SLIDER_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #include "FluentGlobal.h" 12 | 13 | class QPropertyAnimation; 14 | class QPainter; 15 | class QMouseEvent; 16 | 17 | /** 18 | * @brief 滑块手柄组件 19 | */ 20 | class SliderHandle : public QWidget 21 | { 22 | Q_OBJECT 23 | Q_PROPERTY(qreal radius READ radius WRITE setRadius) 24 | 25 | public: 26 | explicit SliderHandle(QSlider* parent); 27 | 28 | qreal radius() const { return m_radius; } 29 | void setRadius(qreal r); 30 | 31 | void setHandleColor(const QColor& light, const QColor& dark); 32 | 33 | signals: 34 | void pressed(); 35 | void released(); 36 | 37 | protected: 38 | #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) 39 | void enterEvent(QEnterEvent *e) override; 40 | #else 41 | void enterEvent(QEvent *e) override; 42 | #endif 43 | void leaveEvent(QEvent* e) override; 44 | void mousePressEvent(QMouseEvent* e) override; 45 | void mouseReleaseEvent(QMouseEvent* e) override; 46 | void paintEvent(QPaintEvent* e) override; 47 | 48 | private: 49 | void startAni(qreal radius); 50 | 51 | qreal m_radius; 52 | QColor m_lightHandleColor; 53 | QColor m_darkHandleColor; 54 | QPropertyAnimation* m_radiusAni; 55 | }; 56 | 57 | 58 | /** 59 | * @brief 可点击的滑块组件 60 | */ 61 | class QFLUENT_EXPORT Slider : public QSlider 62 | { 63 | Q_OBJECT 64 | 65 | public: 66 | explicit Slider(QWidget* parent = nullptr); 67 | explicit Slider(Qt::Orientation orientation, QWidget* parent = nullptr); 68 | 69 | void setThemeColor(const QColor& light, const QColor& dark); 70 | void setOrientation(Qt::Orientation orientation); 71 | 72 | int grooveLength() const; 73 | 74 | signals: 75 | void clicked(int value); 76 | 77 | protected: 78 | void mousePressEvent(QMouseEvent* e) override; 79 | void mouseMoveEvent(QMouseEvent* e) override; 80 | void paintEvent(QPaintEvent* e) override; 81 | void resizeEvent(QResizeEvent* e) override; 82 | 83 | private: 84 | void postInit(); 85 | void adjustHandlePos(); 86 | int posToValue(const QPoint& pos) const; 87 | 88 | void drawHorizonTick(QPainter* painter); 89 | void drawVerticalTick(QPainter* painter); 90 | void drawHorizonGroove(QPainter* painter); 91 | void drawVerticalGroove(QPainter* painter); 92 | 93 | SliderHandle* m_handle; 94 | QPoint m_pressedPos; 95 | QColor m_lightGrooveColor; 96 | QColor m_darkGrooveColor; 97 | }; 98 | 99 | 100 | /** 101 | * @brief 简单的可点击滑块 102 | */ 103 | class QFLUENT_EXPORT ClickableSlider : public QSlider 104 | { 105 | Q_OBJECT 106 | 107 | public: 108 | explicit ClickableSlider(QWidget* parent = nullptr); 109 | explicit ClickableSlider(Qt::Orientation orientation, QWidget* parent = nullptr); 110 | 111 | signals: 112 | void clicked(int value); 113 | 114 | protected: 115 | void mousePressEvent(QMouseEvent* e) override; 116 | }; 117 | 118 | 119 | /** 120 | * @brief 空心手柄样式 121 | */ 122 | class HollowHandleStyle : public QProxyStyle 123 | { 124 | Q_OBJECT 125 | 126 | public: 127 | explicit HollowHandleStyle(const QMap& config = QMap()); 128 | 129 | QRect subControlRect(ComplexControl cc, const QStyleOptionComplex* opt, 130 | SubControl sc, const QWidget* widget = nullptr) const override; 131 | 132 | void drawComplexControl(ComplexControl cc, const QStyleOptionComplex* opt, 133 | QPainter* painter, const QWidget* widget = nullptr) const override; 134 | 135 | private: 136 | QMap m_config; 137 | }; 138 | 139 | #endif // SLIDER_H 140 | -------------------------------------------------------------------------------- /libs/include/QFluent/date_time/DatePicker.h: -------------------------------------------------------------------------------- 1 | #ifndef DATE_PICKER_H 2 | #define DATE_PICKER_H 3 | 4 | #include "PickerBase.h" 5 | #include 6 | #include 7 | 8 | #include "FluentGlobal.h" 9 | 10 | class QCalendar; 11 | class MonthFormatter : public PickerColumnFormatter 12 | { 13 | Q_OBJECT 14 | 15 | public: 16 | explicit MonthFormatter(QObject* parent = nullptr); 17 | QString encode(const QVariant& value) override; 18 | QVariant decode(const QString& value) override; 19 | 20 | private: 21 | QStringList m_months; 22 | }; 23 | 24 | class QFLUENT_EXPORT DatePickerBase : public PickerBase 25 | { 26 | Q_OBJECT 27 | Q_PROPERTY(QDate date READ getDate WRITE setDate) 28 | 29 | public: 30 | explicit DatePickerBase(QWidget* parent = nullptr); 31 | 32 | QDate getDate() const { return m_date; } 33 | virtual void setDate(const QDate& date) = 0; 34 | 35 | void setYearFormatter(PickerColumnFormatter* formatter); 36 | void setMonthFormatter(PickerColumnFormatter* formatter); 37 | void setDayFormatter(PickerColumnFormatter* formatter); 38 | 39 | PickerColumnFormatter* yearFormatter() const; 40 | PickerColumnFormatter* monthFormatter() const; 41 | PickerColumnFormatter* dayFormatter() const; 42 | 43 | public slots: 44 | void reset() override; 45 | 46 | signals: 47 | void dateChanged(const QDate& date); 48 | 49 | protected: 50 | QDate m_date; 51 | QCalendar m_calendar; 52 | PickerColumnFormatter* m_yearFormatter; 53 | PickerColumnFormatter* m_monthFormatter; 54 | PickerColumnFormatter* m_dayFormatter; 55 | }; 56 | 57 | class QFLUENT_EXPORT DatePicker : public DatePickerBase 58 | { 59 | Q_OBJECT 60 | 61 | public: 62 | enum DateFormat { 63 | MM_DD_YYYY = 0, 64 | YYYY_MM_DD = 1 65 | }; 66 | 67 | explicit DatePicker(QWidget* parent = nullptr, DateFormat format = MM_DD_YYYY, bool isMonthTight = true); 68 | 69 | void setDateFormat(DateFormat format); 70 | void setDate(const QDate& date) override; 71 | void setMonthTight(bool isTight); 72 | 73 | protected: 74 | QStringList panelInitialValue() override; 75 | void onConfirmed(const QStringList& value) override; 76 | void onColumnValueChanged(PickerPanel* panel, int index, const QString& value) override; 77 | 78 | private: 79 | int monthColumnWidth(); 80 | 81 | bool m_isMonthTight; 82 | DateFormat m_dateFormat; 83 | int m_monthIndex; 84 | int m_dayIndex; 85 | int m_yearIndex; 86 | QString m_MONTH; 87 | QString m_YEAR; 88 | QString m_DAY; 89 | }; 90 | 91 | class ZhFormatter : public PickerColumnFormatter 92 | { 93 | Q_OBJECT 94 | 95 | public: 96 | explicit ZhFormatter(const QString& suffix, QObject* parent = nullptr); 97 | QString encode(const QVariant& value) override; 98 | QVariant decode(const QString& value) override; 99 | 100 | protected: 101 | QString m_suffix; 102 | }; 103 | 104 | class ZhYearFormatter : public ZhFormatter 105 | { 106 | Q_OBJECT 107 | 108 | public: 109 | explicit ZhYearFormatter(QObject* parent = nullptr) 110 | : ZhFormatter("年", parent) {} 111 | }; 112 | 113 | class ZhMonthFormatter : public ZhFormatter 114 | { 115 | Q_OBJECT 116 | 117 | public: 118 | explicit ZhMonthFormatter(QObject* parent = nullptr) 119 | : ZhFormatter("月", parent) {} 120 | }; 121 | 122 | class ZhDayFormatter : public ZhFormatter 123 | { 124 | Q_OBJECT 125 | 126 | public: 127 | explicit ZhDayFormatter(QObject* parent = nullptr) 128 | : ZhFormatter("日", parent) {} 129 | }; 130 | 131 | class QFLUENT_EXPORT ZhDatePicker : public DatePicker 132 | { 133 | Q_OBJECT 134 | 135 | public: 136 | explicit ZhDatePicker(QWidget* parent = nullptr); 137 | }; 138 | 139 | #endif // DATE_PICKER_H 140 | -------------------------------------------------------------------------------- /src/Window/LoginWindow.cpp: -------------------------------------------------------------------------------- 1 | #include "LoginWindow.h" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "Theme.h" 10 | #include "StyleSheet.h" 11 | #include "QFluent/InfoBar.h" 12 | 13 | LoginWidget::LoginWidget(bool autoLogin) 14 | { 15 | Fluent::WindowButtonHints hints = Fluent::WindowButtonHint::Minimize | 16 | Fluent::WindowButtonHint::Close; 17 | setWindowButtonHints(hints); 18 | // setWindowEffect(ApplicationType::Mica); 19 | 20 | setContentsMargins(0, 0, 0, 0); 21 | setFixedSize(380, 300); 22 | 23 | initUI(); 24 | 25 | if (autoLogin) 26 | QTimer::singleShot(500, this, [=](){ userLogin(); }); 27 | } 28 | 29 | void LoginWidget::initUI() 30 | { 31 | auto w = new QWidget(this); 32 | setCentralWidget(w); 33 | 34 | auto c = new QWidget(w); 35 | c->setFixedWidth(220); 36 | auto hLayout = new QHBoxLayout(w); 37 | hLayout->addStretch(); 38 | hLayout->addWidget(c); 39 | hLayout->addStretch(); 40 | hLayout->setContentsMargins(0, 0, 0, 0); 41 | auto vLayout = new QVBoxLayout(c); 42 | vLayout->setContentsMargins(0, 0, 0, 0); 43 | vLayout->setSpacing(8); 44 | auto imageLabel = new QLabel(this); 45 | imageLabel->setFixedSize(67, 67); 46 | imageLabel->setScaledContents(true); 47 | imageLabel->setPixmap(QPixmap(":res/example.png")); 48 | 49 | m_editUser = new LineEdit(this); 50 | m_editUser->setClearButtonEnabled(true); 51 | m_editUser->setPlaceholderText("请输入用户名"); 52 | m_editUser->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); 53 | 54 | m_editPass = new LineEdit(this); 55 | m_editPass->setClearButtonEnabled(true); 56 | m_editPass->setPlaceholderText("请输入密码"); 57 | m_editPass->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); 58 | m_editPass->setEchoMode(QLineEdit::Password); 59 | 60 | m_autoLogin = new CheckBox("自动登录", this); 61 | 62 | m_btnLogin = new PrimaryPushButton("登 录", this); 63 | m_btnLogin->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); 64 | 65 | vLayout->addWidget(imageLabel, 0, Qt::AlignCenter); 66 | vLayout->addSpacing(5); 67 | vLayout->addWidget(m_editUser); 68 | vLayout->addWidget(m_editPass); 69 | vLayout->addWidget(m_autoLogin, 0, Qt::AlignLeft); 70 | vLayout->addWidget(m_btnLogin); 71 | 72 | vLayout->addStretch(); 73 | 74 | connect(m_editPass, &LineEdit::returnPressed, this, &LoginWidget::onBtnLoginClicked); 75 | connect(m_btnLogin, &PrimaryPushButton::clicked, this, &LoginWidget::onBtnLoginClicked); 76 | } 77 | 78 | void LoginWidget::loading(bool load) 79 | { 80 | static auto _loading = new Loading(QString(), this); 81 | if (load) 82 | _loading->show(); 83 | else 84 | _loading->reject(); 85 | } 86 | 87 | void LoginWidget::onBtnLoginClicked() 88 | { 89 | userLogin(); 90 | } 91 | 92 | void LoginWidget::userLogin() 93 | { 94 | static const QRegularExpression s_whitespaceRegex(QStringLiteral("\\s")); 95 | QString user = m_editUser->text().remove(s_whitespaceRegex); 96 | QString pass = m_editPass->text().remove(s_whitespaceRegex); 97 | 98 | if (user.isEmpty()) { 99 | InfoBar::warning("警告", "用户名不能为空", Qt::Horizontal, false, 2000, Fluent::MessagePosition::TOP, this); 100 | return; 101 | } 102 | if (pass.isEmpty()) { 103 | InfoBar::warning("警告", "密码不能为空", Qt::Horizontal, false, 2000, Fluent::MessagePosition::TOP, this); 104 | return; 105 | } 106 | 107 | loading(true); 108 | 109 | QTimer::singleShot(3000, this, [=](){ 110 | loading(false); 111 | InfoBar::success("提示", "登录成功", Qt::Horizontal, false, 2000, Fluent::MessagePosition::TOP, this); 112 | }); 113 | } 114 | 115 | 116 | 117 | -------------------------------------------------------------------------------- /src/IconInterface.h: -------------------------------------------------------------------------------- 1 | #ifndef ICON_INTERFACE_H 2 | #define ICON_INTERFACE_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | #include "GalleryInterface.h" 18 | 19 | #include "FluentIcon.h" 20 | #include "Theme.h" 21 | #include "FluentGlobal.h" 22 | #include "StyleSheet.h" 23 | #include "QFluent/Label.h" 24 | #include "QFluent/LineEdit.h" 25 | #include "QFluent/PushButton.h" 26 | #include "QFluent/ScrollArea.h" 27 | #include "QFluent/layout/FlowLayout.h" 28 | 29 | 30 | // Trie树实现 31 | class TrieNode { 32 | public: 33 | QMap children; 34 | QVector indexes; // 存储图标索引 35 | 36 | TrieNode(); 37 | ~TrieNode(); 38 | }; 39 | 40 | class Trie { 41 | private: 42 | TrieNode* root; 43 | 44 | public: 45 | Trie(); 46 | ~Trie(); 47 | 48 | void insert(const QString& word, int index); 49 | QVector> items(const QString& prefix); 50 | 51 | private: 52 | void collectWords(TrieNode* node, const QString& prefix, QVector>& results); 53 | }; 54 | 55 | // 搜索框 56 | class CustomLineEdit : public SearchLineEdit { 57 | Q_OBJECT 58 | 59 | public: 60 | explicit CustomLineEdit(QWidget* parent = nullptr); 61 | 62 | signals: 63 | void search(const QString& text); 64 | void clearSignal(); 65 | 66 | private slots: 67 | void onTextChanged(const QString& text); 68 | }; 69 | 70 | // 图标卡片 71 | class IconCard : public QFrame { 72 | Q_OBJECT 73 | 74 | public: 75 | explicit IconCard(Fluent::IconType icon, const QString &name, QWidget* parent = nullptr); 76 | void setSelected(bool isSelected, bool force = false); 77 | 78 | signals: 79 | void clicked(Fluent::IconType icon); 80 | 81 | protected: 82 | void mouseReleaseEvent(QMouseEvent* event) override; 83 | 84 | private: 85 | Fluent::IconType m_icon; 86 | bool m_isSelected; 87 | IconWidget* m_iconWidget; 88 | QLabel* m_nameLabel; 89 | QVBoxLayout* m_vBoxLayout; 90 | }; 91 | 92 | // 图标信息面板 93 | class IconInfoPanel : public QFrame { 94 | Q_OBJECT 95 | 96 | public: 97 | explicit IconInfoPanel(Fluent::IconType icon, QWidget* parent = nullptr); 98 | void setIcon(Fluent::IconType icon); 99 | 100 | private: 101 | QLabel* m_nameLabel; 102 | IconWidget* m_iconWidget; 103 | QLabel* m_iconNameTitleLabel; 104 | QLabel* m_iconNameLabel; 105 | QLabel* m_enumNameTitleLabel; 106 | QLabel* m_enumNameLabel; 107 | QVBoxLayout* m_vBoxLayout; 108 | }; 109 | 110 | 111 | 112 | // 图标卡片视图 113 | class IconCardView : public QWidget { 114 | Q_OBJECT 115 | 116 | public: 117 | explicit IconCardView(QWidget* parent = nullptr); 118 | void addIcon(Fluent::IconType icon, const QString &name); 119 | void setSelectedIcon(Fluent::IconType icon); 120 | 121 | void showAllIcons(); 122 | 123 | private slots: 124 | void search(const QString& text); 125 | 126 | private: 127 | void initWidget(); 128 | void setQss(); 129 | 130 | Trie* m_trie; 131 | StrongBodyLabel* m_iconLibraryLabel; 132 | CustomLineEdit* m_searchLineEdit; 133 | QFrame* m_view; 134 | ScrollArea* m_scrollArea; 135 | QWidget* m_scrollWidget; 136 | IconInfoPanel* m_infoPanel; 137 | QVBoxLayout* m_vBoxLayout; 138 | QHBoxLayout* m_hBoxLayout; 139 | FlowLayout* m_flowLayout; 140 | 141 | QVector m_cards; 142 | QVector m_icons; 143 | int m_currentIndex; 144 | }; 145 | 146 | // 图标界面 147 | class IconInterface : public GalleryInterface { 148 | Q_OBJECT 149 | 150 | public: 151 | explicit IconInterface(QWidget* parent = nullptr); 152 | 153 | private: 154 | IconCardView* m_iconView; 155 | }; 156 | 157 | #endif // ICON_INTERFACE_H 158 | -------------------------------------------------------------------------------- /src/MainWindow.cpp: -------------------------------------------------------------------------------- 1 | #include "MainWindow.h" 2 | 3 | #include "Router.h" 4 | #include "QFluent/navigation/NavigationPanel.h" 5 | #include "QFluent/navigation/NavigationWidget.h" 6 | 7 | #include "FluentIcon.h" 8 | #include "HomeInterface.h" 9 | #include "IconInterface.h" 10 | #include "BasicInputInterface.h" 11 | #include "SettingInterface.h" 12 | #include "DateTimeInputInterface.h" 13 | #include "DialogInputInterface.h" 14 | #include "LayoutInterface.h" 15 | #include "MenuInterface.h" 16 | #include "NavigationViewInterface.h" 17 | #include "ScrollInterface.h" 18 | #include "StatusInfoInterface.h" 19 | #include "TextInterface.h" 20 | #include "ViewInterface.h" 21 | #include "WindowInterface.h" 22 | 23 | #include "ConfigManager.h" 24 | 25 | MainWindow::MainWindow() 26 | { 27 | setWindowTitle("QFluentKit"); 28 | setWindowIcon(QPixmap(":/res/example.png")); 29 | resize(1024, 768); 30 | 31 | setWindowButtonHints(windowButtonHints() | Fluent::WindowButtonHint::RouteBack); 32 | 33 | int theme = ConfigManager::instance().getValue("Window/theme", 0).toInt(); 34 | Theme::instance()->setThemeColor(QColor(ConfigManager::instance().getValue("Window/color", "#0066b4").toString())); 35 | Theme::instance()->setTheme(theme == 0 ? Fluent::ThemeMode::DARK : Fluent::ThemeMode::LIGHT); 36 | 37 | navigationInterface()->setExpandWidth(200); 38 | 39 | QString iconPath = QString(":/res/icons/%1_{color}.svg"); 40 | addSubInterface("1", FluentIcon(Fluent::IconType::HOME), "主页", new HomeInterface(this), true, Fluent::NavigationItemPosition::TOP); 41 | addSubInterface("2", FluentIcon(Fluent::IconType::EMOJI_TAB_SYMBOLS), "图标", new IconInterface(this), true, Fluent::NavigationItemPosition::TOP); 42 | navigationInterface()->addSeparator(); 43 | addSubInterface("3", FluentIcon(Fluent::IconType::CHECKBOX), "基本输入", new BasicInputInterface(this), true, Fluent::NavigationItemPosition::SCROLL); 44 | addSubInterface("4", FluentIcon(Fluent::IconType::DATE_TIME), "日期和时间", new DateTimeInputInterface(this), true, Fluent::NavigationItemPosition::SCROLL); 45 | addSubInterface("5", FluentIcon(Fluent::IconType::MESSAGE), "对话框", new DialogInputInterface(this), true, Fluent::NavigationItemPosition::SCROLL); 46 | addSubInterface("6", FluentIcon(Fluent::IconType::LAYOUT), "布局", new LayoutInterface(this), true, Fluent::NavigationItemPosition::SCROLL); 47 | addSubInterface("7", FluentIcon(iconPath.arg("Menu")), "菜单", new MenuInterface(this), true, Fluent::NavigationItemPosition::SCROLL); 48 | addSubInterface("8", FluentIcon(Fluent::IconType::MENU), "导航", new NavigationViewInterface(this), true, Fluent::NavigationItemPosition::SCROLL); 49 | addSubInterface("9", FluentIcon(Fluent::IconType::APPLICATION), "窗口", new WindowInterface(this), true, Fluent::NavigationItemPosition::SCROLL); 50 | addSubInterface("10", FluentIcon(Fluent::IconType::SCROLL), "滚动", new ScrollInterface(this), true, Fluent::NavigationItemPosition::SCROLL); 51 | addSubInterface("11", FluentIcon(Fluent::IconType::CHAT), "状态", new StatusInfoInterface(this), true, Fluent::NavigationItemPosition::SCROLL); 52 | addSubInterface("12", FluentIcon(iconPath.arg("Text")), "文本", new TextInterface(this), true, Fluent::NavigationItemPosition::SCROLL); 53 | addSubInterface("13", FluentIcon(iconPath.arg("Grid")), "视图", new ViewInterface(this), true, Fluent::NavigationItemPosition::SCROLL); 54 | 55 | navigationInterface()->addSeparator(Fluent::NavigationItemPosition::BOTTOM); 56 | addSubInterface("14", FluentIcon(Fluent::IconType::SETTING), "设置", new SettingInterface(this), true, Fluent::NavigationItemPosition::BOTTOM); 57 | 58 | qrouter->setDefaultRouteKey(stackedWidget(), "homeInterface"); 59 | navigationInterface()->setCurrentItem("1"); 60 | 61 | NavigationAvatarWidget* avatar = navigationInterface()->avatarWidget(); 62 | avatar->setName("Administrator"); 63 | avatar->setAvatar(QImage(":/res/avatar.png")); 64 | 65 | connect(this, &MainWindow::backRequested, this, [=](){ 66 | qrouter->pop(); 67 | }); 68 | } 69 | 70 | void MainWindow::setCurrentInterface(const QString &routeKey, int index) 71 | { 72 | qrouter->push(stackedWidget(), routeKey); 73 | navigationInterface()->setCurrentItem(QString::number(index)); 74 | } 75 | -------------------------------------------------------------------------------- /src/StatusInfoInterface.cpp: -------------------------------------------------------------------------------- 1 | #include "StatusInfoInterface.h" 2 | 3 | #include "Theme.h" 4 | #include "QFluent/Label.h" 5 | #include "QFluent/SpinBox.h" 6 | #include "QFluent/InfoBar.h" 7 | #include "QFluent/PushButton.h" 8 | #include "QFluent/progress/ProgressBar.h" 9 | #include "QFluent/progress/ProgressRing.h" 10 | #include "QFluent/progress/IndeterminateProgressBar.h" 11 | #include "QFluent/progress/IndeterminateProgressRing.h" 12 | 13 | StatusInfoInterface::StatusInfoInterface(QWidget *parent) 14 | : GalleryInterface("状态", "", parent) 15 | { 16 | setObjectName("StatusInfoInterface"); 17 | 18 | auto w = new QWidget(this); 19 | auto hBoxLayout = new QHBoxLayout(w); 20 | auto btn1 = new PushButton("右上角", w); 21 | auto btn2 = new PushButton("顶部居中", w); 22 | auto btn3 = new PushButton("左上角", w); 23 | auto btn4 = new PushButton("右下角", w); 24 | auto btn5 = new PushButton("底部居中", w); 25 | auto btn6 = new PushButton("左下角", w); 26 | connect(btn1, &PushButton::clicked, this, [=](){ 27 | InfoBar::info("你看", "我有几分像从前?", Qt::Horizontal, false, 2000, Fluent::MessagePosition::TOP_RIGHT, this); 28 | }); 29 | connect(btn2, &PushButton::clicked, this, [=](){ 30 | InfoBar::success("你看", "我有几分有几分有几分有几分有几分有几分有几分有几分有几分有几分有几分有几分有几分有几分" 31 | "有几分有几分有几分有几分有几分有几分有几分有几分有几分有几分有几分有几分有几分有几分像从前?", 32 | Qt::Horizontal, true, 2000, Fluent::MessagePosition::TOP, this); 33 | }); 34 | connect(btn3, &PushButton::clicked, this, [=](){ 35 | InfoBar::warning("你看", "我有几分像从前?", Qt::Horizontal, false, 2000, Fluent::MessagePosition::TOP_LEFT, this); 36 | }); 37 | connect(btn4, &PushButton::clicked, this, [=](){ 38 | InfoBar::error("你看", "我有几分像从前?", Qt::Horizontal, false, 2000, Fluent::MessagePosition::BOTTOM_RIGHT, this); 39 | }); 40 | connect(btn5, &PushButton::clicked, this, [=](){ 41 | InfoBar::success("你看", "我有几分像从前?", Qt::Horizontal, false, 2000, Fluent::MessagePosition::BOTTOM, this); 42 | }); 43 | connect(btn6, &PushButton::clicked, this, [=](){ 44 | InfoBar::warning("你看", "我有几分像从前?", Qt::Horizontal, false, 2000, Fluent::MessagePosition::BOTTOM_LEFT, this); 45 | }); 46 | hBoxLayout->addWidget(btn1); 47 | hBoxLayout->addWidget(btn2); 48 | hBoxLayout->addWidget(btn3); 49 | hBoxLayout->addWidget(btn4); 50 | hBoxLayout->addWidget(btn5); 51 | hBoxLayout->addWidget(btn6); 52 | hBoxLayout->setContentsMargins(0, 0, 0, 0); 53 | hBoxLayout->setSpacing(15); 54 | 55 | addExampleCard("不同弹出位置的消息条", w); 56 | 57 | QColor color = Theme::instance()->themeColor(); 58 | auto indeterminateProgressBar = new IndeterminateProgressBar(this); 59 | indeterminateProgressBar->setFixedWidth(200); 60 | addExampleCard("不确定进度条", indeterminateProgressBar); 61 | 62 | auto progressBar = new ProgressBar(this); 63 | progressBar->setFixedWidth(200); 64 | progressBar->setValue(50); 65 | addExampleCard("确定的进度条", createProgressWidget(progressBar)); 66 | 67 | auto indeterminateProgressRing = new IndeterminateProgressRing(this); 68 | indeterminateProgressRing->setFixedSize(70, 70); 69 | addExampleCard("不确定进度环", indeterminateProgressRing); 70 | 71 | auto progressRing = new ProgressRing(this); 72 | progressRing->setValue(50); 73 | progressRing->setFixedSize(70, 70); 74 | addExampleCard("确定的进度环", createProgressWidget(progressRing)); 75 | } 76 | 77 | 78 | QWidget* StatusInfoInterface::createProgressWidget(QProgressBar *widget) 79 | { 80 | auto w = new QWidget(this); 81 | auto hBoxLayout = new QHBoxLayout(w); 82 | auto spinBox = new SpinBox(w); 83 | spinBox->setValue(50); 84 | spinBox->setRange(0, 100); 85 | 86 | hBoxLayout->addWidget(widget); 87 | hBoxLayout->addSpacing(50); 88 | hBoxLayout->addWidget(new BodyLabel("进度", w)); 89 | hBoxLayout->addSpacing(5); 90 | hBoxLayout->addWidget(spinBox); 91 | setContentsMargins(0, 0, 0, 0); 92 | 93 | connect(spinBox, QOverload::of(&SpinBox::valueChanged), this, [this, widget](int value){ 94 | widget->setValue(value); 95 | }); 96 | 97 | return w; 98 | } 99 | 100 | --------------------------------------------------------------------------------