| Ya Zaregalsya |
29.12.2020 15:44 |
• Исходники Qt опубликованы на ГитХабе. Файлы по искомой теме:
qwindow .cpp/.h;
qeventloop .cpp/.h;
qabstracteventdistatcher.cpp/.h;
qcoreapplication .cpp/ .h;
qguiapplication.cpp/.h;
qwindowsysteminterface.cpp/.h/_p.h(судя по всему, здесь Qt захватывает события из Windows);
qcoreevent .cpp/ .h (здесь реализован класс QEvent);
qevent .cpp/ .h (QInputEvent, QMouseEvent);
qinputdevice .cpp/ .h;
qwindowsmousehandler.cpp/.h;
https://code.woboq.org/qt5/qtbase/s...entLoop4execE6QFlagsINS_17ProcessEventsFlagEE
https://code.woboq.org/qt5/qtbase/src/gui/kernel/qguiapplication.cpp.html#1896(а здесь Qt уже разбирает события Windows);
https://code.woboq.org/qt5/qtbase/s...SystemInterfacePrivate::WindowSystemEventList
https://code.woboq.org/qt5/qtbase/s...dowSystemInterfacePrivate17WindowSystemEventE
Цитата:
Сообщение от Спойлер
QEvent
|
QInputEvent
|
QPointerEvent
|
QSinglePointEvent
|
QMouseEvent
|
Цитата:
Сообщение от Спойлер
Цитата:
/*!
\class QEvent
\inmodule QtCore
\brief The QEvent class is the base class of all
event classes. Event objects contain event parameters.
\ingroup events
Qt's main event loop (QCoreApplication::exec()) fetches native
window system events from the event queue, translates them into
QEvents, and sends the translated events to \l{QObject}s.
In general, events come from the underlying window system
(spontaneous() returns \c true), but it is also possible to manually
send events using QCoreApplication::sendEvent() and
QCoreApplication::postEvent() (spontaneous() returns \c false).
\l {QObject}{QObjects} receive events by having their QObject::event() function
called. The function can be reimplemented in subclasses to
customize event handling and add additional event types;
QWidget::event() is a notable example. By default, events are
dispatched to event handlers like QObject::timerEvent() and
QWidget::mouseMoveEvent(). QObject::installEventFilter() allows an
object to intercept events destined for another object.
The basic QEvent contains only an event type parameter and an
"accept" flag. The accept flag set with accept(), and cleared
with ignore(). It is set by default, but don't rely on this as
subclasses may choose to clear it in their constructor.
Subclasses of QEvent contain additional parameters that describe
the particular event.
\sa QObject::event(), QObject::installEventFilter(),
QCoreApplication::sendEvent(),
QCoreApplication::postEvent(), QCoreApplication::processEvents()
*/
|
|
Цитата:
Сообщение от Спойлер
Цитата:
Detailed DescriptionThis class is used by non-GUI applications to provide their event loop. For non-GUI application that uses Qt, there should be exactly one QCoreApplication object. For GUI applications, seeQGuiApplication. For applications that use the Qt Widgets module, see QApplication.
QCoreApplication contains the main event loop, where all events from the operating system (e.g., timer and network events) and other sources are processed and dispatched. It also handles the application's initialization and finalization, as well as system-wide and application-wide settings.
The Event Loop and Event HandlingThe event loop is started with a call to exec(). Long-running operations can call processEvents() to keep the application responsive.
In general, we recommend that you create a QCoreApplication, QGuiApplication or a QApplication object in your main() function as early as possible. exec() will not return until the event loop exits; e.g., when quit() is called.
Several static convenience functions are also provided. The QCoreApplication object is available from instance(). Events can be sent with sendEvent() or posted to an event queue with postEvent(). Pending events can be removed with removePostedEvents() or dispatched with sendPostedEvents().
The class provides a quit() slot and an aboutToQuit() signal.
|
|
Цитата:
Сообщение от Спойлер
C++:
Код:
void
QGuiApplicationPrivate
::
processWindowSystemEvent
(
QWindowSystemInterfacePrivate
::
WindowSystemEvent
*
e
)
{
Q_TRACE_SCOPE
(
QGuiApplicationPrivate_processWindowSystemEvent
,
e
->
type
)
;
switch
(
e
->
type
)
{
case
QWindowSystemInterfacePrivate
::
Mouse
:
QGuiApplicationPrivate
::
processMouseEvent
(
static_cast
(
e
)
)
;
break
;
case
QWindowSystemInterfacePrivate
::
Wheel
:
QGuiApplicationPrivate
::
processWheelEvent
(
static_cast
(
e
)
)
;
break
;
case
QWindowSystemInterfacePrivate
::
Key
:
QGuiApplicationPrivate
::
processKeyEvent
(
static_cast
(
e
)
)
;
break
;
case
QWindowSystemInterfacePrivate
::
Touch
:
QGuiApplicationPrivate
::
processTouchEvent
(
static_cast
(
e
)
)
;
break
;
case
QWindowSystemInterfacePrivate
::
GeometryChange
:
QGuiApplicationPrivate
::
processGeometryChangeEvent
(
static_cast
(
e
)
)
;
break
;
case
QWindowSystemInterfacePrivate
::
Enter
:
QGuiApplicationPrivate
::
processEnterEvent
(
static_cast
(
e
)
)
;
break
;
case
QWindowSystemInterfacePrivate
::
Leave
:
QGuiApplicationPrivate
::
processLeaveEvent
(
static_cast
(
e
)
)
;
break
;
case
QWindowSystemInterfacePrivate
::
ActivatedWindow
:
QGuiApplicationPrivate
::
processActivatedEvent
(
static_cast
(
e
)
)
;
break
;
case
QWindowSystemInterfacePrivate
::
WindowStateChanged
:
QGuiApplicationPrivate
::
processWindowStateChangedEvent
(
static_cast
(
e
)
)
;
break
;
case
QWindowSystemInterfacePrivate
::
WindowScreenChanged
:
QGuiApplicationPrivate
::
processWindowScreenChangedEvent
(
static_cast
(
e
)
)
;
break
;
case
QWindowSystemInterfacePrivate
::
SafeAreaMarginsChanged
:
QGuiApplicationPrivate
::
processSafeAreaMarginsChangedEvent
(
static_cast
(
e
)
)
;
break
;
case
QWindowSystemInterfacePrivate
::
ApplicationStateChanged
:
{
QWindowSystemInterfacePrivate
::
ApplicationStateChangedEvent
*
changeEvent
=
static_cast
(
e
)
;
QGuiApplicationPrivate
::
setApplicationState
(
changeEvent
->
newState
,
changeEvent
->
forcePropagate
)
;
}
break
;
case
QWindowSystemInterfacePrivate
::
FlushEvents
:
{
QWindowSystemInterfacePrivate
::
FlushEventsEvent
*
flushEventsEvent
=
static_cast
(
e
)
;
QWindowSystemInterface
::
deferredFlushWindowSystemEvents
(
flushEventsEvent
->
flags
)
;
}
break
;
case
QWindowSystemInterfacePrivate
::
Close
:
QGuiApplicationPrivate
::
processCloseEvent
(
static_cast
(
e
)
)
;
break
;
case
QWindowSystemInterfacePrivate
::
ScreenOrientation
:
QGuiApplicationPrivate
::
processScreenOrientationChange
(
static_cast
(
e
)
)
;
break
;
case
QWindowSystemInterfacePrivate
::
ScreenGeometry
:
QGuiApplicationPrivate
::
processScreenGeometryChange
(
static_cast
(
e
)
)
;
break
;
case
QWindowSystemInterfacePrivate
::
ScreenLogicalDotsPerInch
:
QGuiApplicationPrivate
::
processScreenLogicalDotsPerInchChange
(
static_cast
(
e
)
)
;
break
;
case
QWindowSystemInterfacePrivate
::
ScreenRefreshRate
:
QGuiApplicationPrivate
::
processScreenRefreshRateChange
(
static_cast
(
e
)
)
;
break
;
case
QWindowSystemInterfacePrivate
::
ThemeChange
:
QGuiApplicationPrivate
::
processThemeChanged
(
static_cast
(
e
)
)
;
break
;
case
QWindowSystemInterfacePrivate
::
Expose
:
QGuiApplicationPrivate
::
processExposeEvent
(
static_cast
(
e
)
)
;
break
;
case
QWindowSystemInterfacePrivate
::
Tablet
:
QGuiApplicationPrivate
::
processTabletEvent
(
static_cast
(
e
)
)
;
break
;
case
QWindowSystemInterfacePrivate
::
TabletEnterProximity
:
QGuiApplicationPrivate
::
processTabletEnterProximityEvent
(
static_cast
(
e
)
)
;
break
;
case
QWindowSystemInterfacePrivate
::
TabletLeaveProximity
:
QGuiApplicationPrivate
::
processTabletLeaveProximityEvent
(
static_cast
(
e
)
)
;
break
;
#ifndef QT_NO_GESTURES
case
QWindowSystemInterfacePrivate
::
Gesture
:
QGuiApplicationPrivate
::
processGestureEvent
(
static_cast
(
e
)
)
;
break
;
#endif
case
QWindowSystemInterfacePrivate
::
PlatformPanel
:
QGuiApplicationPrivate
::
processPlatformPanelEvent
(
static_cast
(
e
)
)
;
break
;
case
QWindowSystemInterfacePrivate
::
FileOpen
:
QGuiApplicationPrivate
::
processFileOpenEvent
(
static_cast
(
e
)
)
;
break
;
#ifndef QT_NO_CONTEXTMENU
case
QWindowSystemInterfacePrivate
::
ContextMenu
:
QGuiApplicationPrivate
::
processContextMenuEvent
(
static_cast
(
e
)
)
;
break
;
#endif
case
QWindowSystemInterfacePrivate
::
EnterWhatsThisMode
:
QGuiApplication
::
postEvent
(
QGuiApplication
::
instance
(
)
,
new
QEvent
(
QEvent
::
EnterWhatsThisMode
)
)
;
break
;
default
:
qWarning
(
)
type
;
break
;
}
}
C++:
Код:
void
QGuiApplicationPrivate
::
processMouseEvent
(
QWindowSystemInterfacePrivate
::
MouseEvent
*
e
)
{
QEvent
::
Type type
=
QEvent
::
None
;
Qt
::
MouseButton button
=
Qt
::
NoButton
;
QWindow
*
window
=
e
->
window
.
data
(
)
;
bool
positionChanged
=
QGuiApplicationPrivate
::
lastCursorPosition
!=
e
->
globalPos
;
bool
mouseMove
=
false
;
bool
mousePress
=
false
;
if
(
e
->
enhancedMouseEvent
(
)
)
{
type
=
e
->
buttonType
;
button
=
e
->
button
;
if
(
type
==
QEvent
::
NonClientAreaMouseMove
||
type
==
QEvent
::
MouseMove
)
mouseMove
=
true
;
else
if
(
type
==
QEvent
::
NonClientAreaMouseButtonPress
||
type
==
QEvent
::
MouseButtonPress
)
mousePress
=
true
;
if
(
!
mouseMove
&&
positionChanged
)
{
QWindowSystemInterfacePrivate
::
MouseEvent
moveEvent
(
window
,
e
->
timestamp
,
e
->
localPos
,
e
->
globalPos
,
e
->
buttons
^
button
,
e
->
modifiers
,
Qt
::
NoButton
,
e
->
nonClientArea
?
QEvent
::
NonClientAreaMouseMove
:
QEvent
::
MouseMove
,
e
->
source
,
e
->
nonClientArea
)
;
if
(
e
->
synthetic
(
)
)
moveEvent
.
flags
|=
QWindowSystemInterfacePrivate
::
WindowSystemEvent
::
Synthetic
;
processMouseEvent
(
&
moveEvent
)
;
// mouse move excluding state change
processMouseEvent
(
e
)
;
// the original mouse event
return
;
}
}
else
{
Qt
::
MouseButtons stateChange
=
e
->
buttons
^
mouse_buttons
;
if
(
positionChanged
&&
(
stateChange
!=
Qt
::
NoButton
)
)
{
QWindowSystemInterfacePrivate
::
MouseEvent
moveEvent
(
window
,
e
->
timestamp
,
e
->
localPos
,
e
->
globalPos
,
mouse_buttons
,
e
->
modifiers
,
Qt
::
NoButton
,
QEvent
::
None
,
e
->
source
,
e
->
nonClientArea
)
;
if
(
e
->
synthetic
(
)
)
moveEvent
.
flags
|=
QWindowSystemInterfacePrivate
::
WindowSystemEvent
::
Synthetic
;
processMouseEvent
(
&
moveEvent
)
;
// mouse move excluding state change
processMouseEvent
(
e
)
;
// the original mouse event
return
;
}
// In the compatibility path we deduce event type and button that caused the event
if
(
positionChanged
)
{
mouseMove
=
true
;
type
=
e
->
nonClientArea
?
QEvent
::
NonClientAreaMouseMove
:
QEvent
::
MouseMove
;
}
else
{
// Check to see if a new button has been pressed/released.
for
(
uint mask
=
Qt
::
LeftButton
;
mask
buttons
)
{
mousePress
=
true
;
type
=
e
->
nonClientArea
?
QEvent
::
NonClientAreaMouseButtonPress
:
QEvent
::
MouseButtonPress
;
}
else
{
type
=
e
->
nonClientArea
?
QEvent
::
NonClientAreaMouseButtonRelease
:
QEvent
::
MouseButtonRelease
;
}
}
}
modifier_buttons
=
e
->
modifiers
;
QPointF localPoint
=
e
->
localPos
;
QPointF globalPoint
=
e
->
globalPos
;
bool
doubleClick
=
false
;
if
(
mouseMove
)
{
QGuiApplicationPrivate
::
lastCursorPosition
=
globalPoint
;
const
auto
doubleClickDistance
=
e
->
source
==
Qt
::
MouseEventNotSynthesized
?
mouseDoubleClickDistance
:
touchDoubleTapDistance
;
if
(
qAbs
(
globalPoint
.
x
(
)
-
mousePressX
)
>
doubleClickDistance
||
qAbs
(
globalPoint
.
y
(
)
-
mousePressY
)
>
doubleClickDistance
)
mousePressButton
=
Qt
::
NoButton
;
}
else
{
mouse_buttons
=
e
->
buttons
;
if
(
mousePress
)
{
ulong doubleClickInterval
=
static_cast
(
QGuiApplication
::
styleHints
(
)
->
mouseDoubleClickInterval
(
)
)
;
doubleClick
=
e
->
timestamp
-
mousePressTime
timestamp
;
mousePressButton
=
button
;
const
QPoint point
=
QGuiApplicationPrivate
::
lastCursorPosition
.
toPoint
(
)
;
mousePressX
=
point
.
x
(
)
;
mousePressY
=
point
.
y
(
)
;
}
}
if
(
e
->
nullWindow
(
)
)
{
window
=
QGuiApplication
::
topLevelAt
(
globalPoint
.
toPoint
(
)
)
;
if
(
window
)
{
// Moves and the release following a press must go to the same
// window, even if the cursor has moved on over another window.
if
(
e
->
buttons
!=
Qt
::
NoButton
)
{
if
(
!
currentMousePressWindow
)
currentMousePressWindow
=
window
;
else
window
=
currentMousePressWindow
;
}
else
if
(
currentMousePressWindow
)
{
window
=
currentMousePressWindow
;
currentMousePressWindow
=
0
;
}
QPointF delta
=
globalPoint
-
globalPoint
.
toPoint
(
)
;
localPoint
=
window
->
mapFromGlobal
(
globalPoint
.
toPoint
(
)
)
+
delta
;
}
}
if
(
!
window
)
return
;
#ifndef QT_NO_CURSOR
if
(
!
e
->
synthetic
(
)
)
{
if
(
const
QScreen
*
screen
=
window
->
screen
(
)
)
if
(
QPlatformCursor
*
cursor
=
screen
->
handle
(
)
->
cursor
(
)
)
{
const
QPointF nativeLocalPoint
=
QHighDpi
::
toNativePixels
(
localPoint
,
screen
)
;
const
QPointF nativeGlobalPoint
=
QHighDpi
::
toNativePixels
(
globalPoint
,
screen
)
;
QMouseEvent
ev
(
type
,
nativeLocalPoint
,
nativeLocalPoint
,
nativeGlobalPoint
,
button
,
e
->
buttons
,
e
->
modifiers
,
e
->
source
)
;
ev
.
setTimestamp
(
e
->
timestamp
)
;
cursor
->
pointerEvent
(
ev
)
;
}
}
#endif
QMouseEvent
ev
(
type
,
localPoint
,
localPoint
,
globalPoint
,
button
,
e
->
buttons
,
e
->
modifiers
,
e
->
source
)
;
ev
.
setTimestamp
(
e
->
timestamp
)
;
if
(
window
->
d_func
(
)
->
blockedByModalWindow
&&
!
qApp
->
d_func
(
)
->
popupActive
(
)
)
{
// a modal window is blocking this window, don't allow mouse events through
return
;
}
if
(
doubleClick
&&
(
ev
.
type
(
)
==
QEvent
::
MouseButtonPress
)
)
{
// QtBUG-25831, used to suppress delivery in qwidgetwindow.cpp
setMouseEventFlags
(
&
ev
,
ev
.
flags
(
)
|
Qt
::
MouseEventCreatedDoubleClick
)
;
}
QGuiApplication
::
sendSpontaneousEvent
(
window
,
&
ev
)
;
e
->
eventAccepted
=
ev
.
isAccepted
(
)
;
if
(
!
e
->
synthetic
(
)
&&
!
ev
.
isAccepted
(
)
&&
!
e
->
nonClientArea
&&
qApp
->
testAttribute
(
Qt
::
AA_SynthesizeTouchForUnhandledMouseEvents
)
)
{
if
(
!
m_fakeTouchDevice
)
{
m_fakeTouchDevice
=
new
QTouchDevice
;
QWindowSystemInterface
::
registerTouchDevice
(
m_fakeTouchDevice
)
;
}
QList
points
;
QWindowSystemInterface
::
TouchPoint point
;
point
.
id
=
1
;
point
.
area
=
QRectF
(
globalPoint
.
x
(
)
-
2
,
globalPoint
.
y
(
)
-
2
,
4
,
4
)
;
// only translate left button related events to
// avoid strange touch event sequences when several
// buttons are pressed
if
(
type
==
QEvent
::
MouseButtonPress
&&
button
==
Qt
::
LeftButton
)
{
point
.
state
=
Qt
::
TouchPointPressed
;
}
else
if
(
type
==
QEvent
::
MouseButtonRelease
&&
button
==
Qt
::
LeftButton
)
{
point
.
state
=
Qt
::
TouchPointReleased
;
}
else
if
(
type
==
QEvent
::
MouseMove
&&
(
e
->
buttons
&
Qt
::
LeftButton
)
)
{
point
.
state
=
Qt
::
TouchPointMoved
;
}
else
{
return
;
}
points
touchPoints
=
QWindowSystemInterfacePrivate
::
fromNativeTouchPoints
(
points
,
window
,
QTouchDevicePrivate
::
get
(
m_fakeTouchDevice
)
->
id
,
&
type
)
;
QWindowSystemInterfacePrivate
::
TouchEvent
fake
(
window
,
e
->
timestamp
,
type
,
m_fakeTouchDevice
,
touchPoints
,
e
->
modifiers
)
;
fake
.
flags
|=
QWindowSystemInterfacePrivate
::
WindowSystemEvent
::
Synthetic
;
processTouchEvent
(
&
fake
)
;
}
if
(
doubleClick
)
{
mousePressButton
=
Qt
::
NoButton
;
if
(
!
e
->
window
.
isNull
(
)
||
e
->
nullWindow
(
)
)
{
// QTBUG-36364, check if window closed in response to press
const
QEvent
::
Type doubleClickType
=
e
->
nonClientArea
?
QEvent
::
NonClientAreaMouseButtonDblClick
:
QEvent
::
MouseButtonDblClick
;
QMouseEvent
dblClickEvent
(
doubleClickType
,
localPoint
,
localPoint
,
globalPoint
,
button
,
e
->
buttons
,
e
->
modifiers
,
e
->
source
)
;
dblClickEvent
.
setTimestamp
(
e
->
timestamp
)
;
QGuiApplication
::
sendSpontaneousEvent
(
window
,
&
dblClickEvent
)
;
}
}
}
|
|