QtCanpool 3.3.0
载入中...
搜索中...
未找到
ribbonwindow.cpp
浏览该文件的文档.
1
5#include "ribbonwindow.h"
6#include "framelesshelper.h"
7#include "windowbuttongroup.h"
8
9#include <QApplication>
10
12
13class RibbonWindowPrivate
14{
15 QX_DECLARE_PUBLIC(RibbonWindow)
16public:
17 RibbonWindowPrivate();
18 void destroyFrameless();
19 void setFrameless(bool frameless);
20 void init();
21public:
22 WindowButtonGroup *m_windowButtonGroup;
23 FramelessHelper *m_framelessHelper;
24 bool m_frameless;
25};
26
27RibbonWindowPrivate::RibbonWindowPrivate()
28 : m_windowButtonGroup(Q_NULLPTR)
29 , m_framelessHelper(Q_NULLPTR)
30 , m_frameless(true)
31{
32}
33
34void RibbonWindowPrivate::destroyFrameless()
35{
36 Q_Q(RibbonWindow);
37 RibbonBar *rb = q->ribbonBar();
38
39 if (m_framelessHelper) {
40 delete m_framelessHelper;
41 m_framelessHelper = Q_NULLPTR;
42 }
43 if (m_windowButtonGroup) {
44 m_windowButtonGroup->hide();
45 if (rb) {
46 rb->setWindowButtonGroup(Q_NULLPTR);
47 }
48 delete m_windowButtonGroup;
49 m_windowButtonGroup = Q_NULLPTR;
50 }
51}
52
53void RibbonWindowPrivate::setFrameless(bool frameless)
54{
55 Q_Q(RibbonWindow);
56 RibbonBar *rb = q->ribbonBar();
57
58 // The following call to setWindowFlags will cause the widget to hide.
59 // Here, we first obtain the show status of the widget to determine
60 // whether it is from shown to hidden or from hidden to hidden
61 bool isHidden = q->isHidden();
62
63 if (frameless) {
64 if (Q_NULLPTR == m_framelessHelper) {
65 m_framelessHelper = new FramelessHelper(q);
66 }
67 m_framelessHelper->setTitleHeight(rb->titleBarHeight());
68 m_framelessHelper->addCaptionClassName("QxRibbon::RibbonBar");
69 if (Q_NULLPTR == m_windowButtonGroup) {
70 m_windowButtonGroup = new WindowButtonGroup(q);
71 if (rb) {
72 rb->setWindowButtonGroup(m_windowButtonGroup);
73 }
74 }
75 Qt::WindowStates s = q->windowState();
76 if (s.testFlag(Qt::WindowFullScreen)) {
77 m_windowButtonGroup->setVisible(false);
78 } else {
79 m_windowButtonGroup->setVisible(true);
80 }
81 m_windowButtonGroup->setWindowStates(s);
82 q->setWindowFlags(q->windowFlags() | Qt::FramelessWindowHint);
83 } else {
84 destroyFrameless();
85 q->setWindowFlags(q->windowFlags() & ~Qt::FramelessWindowHint);
86 }
87
88 if (!isHidden) {
89 // from shown to hidden, so call show() to make the widget shown again
90 q->show();
91 }
92}
93
94void RibbonWindowPrivate::init()
95{
96 setFrameless(m_frameless);
97}
98
99RibbonWindow::RibbonWindow(QWidget *parent)
100 : RibbonMainWindow(parent)
101{
103 Q_D(RibbonWindow);
104 d->init();
105 resizeRibbon();
106}
107
112
114{
115 Q_D(const RibbonWindow);
116 return d->m_frameless;
117}
118
119void RibbonWindow::setFrameless(bool frameless)
120{
121 Q_D(RibbonWindow);
122 if (d->m_frameless == frameless) {
123 return;
124 }
125 d->m_frameless = frameless;
126 d->setFrameless(frameless);
127 ribbonBar()->setWindowTitleVisible(frameless);
128 resizeRibbon();
129}
130
131void RibbonWindow::updateWindowFlags(Qt::WindowFlags flags)
132{
133 Q_D(RibbonWindow);
134 setWindowFlags(flags);
135 // Note: This function setWindowFlags calls setParent() when changing the flags for a window,
136 // causing the widget to be hidden. You must call show() to make the widget visible again..
137 show();
138 if (isFrameless() && d->m_windowButtonGroup) {
139 d->m_windowButtonGroup->updateWindowFlags(flags);
140 // FIXME: In the WpsLiteStyle style, there is a short time overlap between rightButtonGroup and
141 // windowButtonGroup. Because the button group will be displayed first, and then resize the ribbon.
142 // I tried to hide the button group first and display the button group after resize ribbon,
143 // but because resize ribbon is a trigger event and non-blocking, the button group was displayed
144 // before resize was completed, so I failed.
145 resizeRibbon();
146 }
147}
148
149bool RibbonWindow::eventFilter(QObject *obj, QEvent *e)
150{
151 if (isFrameless()) {
152 // event post ribbonBar -> mainwindow -> framelessHelper
153 if (obj == ribbonBar()) {
154 switch (e->type()) {
155 case QEvent::MouseButtonPress:
156 case QEvent::MouseButtonRelease:
157 case QEvent::MouseMove:
158 case QEvent::Leave:
159 case QEvent::HoverMove:
160 case QEvent::MouseButtonDblClick:
161 QApplication::sendEvent(this, e); // post to framelessHelper
162 default:
163 break;
164 }
165 }
166 }
167 return RibbonMainWindow::eventFilter(obj, e);
168}
169
170bool RibbonWindow::event(QEvent *e)
171{
172 Q_D(RibbonWindow);
173 switch (e->type()) {
174 case QEvent::WindowStateChange: {
175 Qt::WindowStates s = windowState();
176 if (isFrameless() && d->m_windowButtonGroup) {
177 if (s.testFlag(Qt::WindowFullScreen)) {
178 d->m_windowButtonGroup->setVisible(false);
179 } else {
180 d->m_windowButtonGroup->setVisible(true);
181 }
182 d->m_windowButtonGroup->setWindowStates(s);
183 resizeRibbon();
184 }
185 Q_EMIT windowStateChanged(s);
186 } break;
187 default:
188 break;
189 }
190 return RibbonMainWindow::event(e);
191}
192
void setWindowTitleVisible(bool visible)
virtual bool eventFilter(QObject *obj, QEvent *event) override
virtual bool event(QEvent *e) override
void windowStateChanged(Qt::WindowStates state)
RibbonBar * ribbonBar() const
如果要使用 RibbonBar,必须使用 RibbonWindow 代替 QMainWindow
void updateWindowFlags(Qt::WindowFlags flags) override
virtual bool event(QEvent *e) override
virtual bool eventFilter(QObject *obj, QEvent *e) override
void setFrameless(bool frameless)
#define QX_INIT_PRIVATE(Class)
#define QX_DECLARE_PUBLIC(Class)
#define Q_NULLPTR
Copyleft (C) 2025 maminjie canpool@163.com SPDX-License-Identifier: MulanPSL-2.0
#define QX_FINI_PRIVATE()
#define QX_RIBBON_END_NAMESPACE
#define QX_RIBBON_BEGIN_NAMESPACE