8#include "platformtheme.h"
9#include "basictheme_p.h"
10#include "platformpluginfactory.h"
13#include <QFontDatabase>
14#include <QGuiApplication>
15#include <QPluginLoader>
20#include <QQuickWindow>
26#include <unordered_map>
48struct TypeInitializer {
58static TypeInitializer initializer;
63class PlatformThemeData :
public QObject
83 AlternateBackgroundColor,
85 ActiveBackgroundColor,
87 VisitedLinkBackgroundColor,
88 NegativeBackgroundColor,
89 NeutralBackgroundColor,
90 PositiveBackgroundColor,
99 using ColorMap = std::unordered_map<std::underlying_type<ColorRole>::type, QColor>;
103 QPointer<PlatformTheme> owner;
106 PlatformTheme::ColorGroup colorGroup = PlatformTheme::Active;
108 std::array<QColor, ColorRoleCount> colors;
120 using Watcher = PlatformTheme *;
121 QList<Watcher> watchers;
125 if (
sender != owner || colorSet == set) {
129 auto oldValue = colorSet;
133 notifyWatchers<PlatformTheme::ColorSet>(
sender, oldValue, set);
136 inline void setColorGroup(PlatformTheme *
sender, PlatformTheme::ColorGroup group)
138 if (
sender != owner || colorGroup == group) {
142 auto oldValue = colorGroup;
147 notifyWatchers<PlatformTheme::ColorGroup>(
sender, oldValue, group);
150 inline void setColor(PlatformTheme *
sender, ColorRole role,
const QColor &color)
152 if (
sender != owner || colors[role] == color) {
156 auto oldValue = colors[role];
158 colors[role] = color;
159 updatePalette(palette, colors);
161 notifyWatchers<QColor>(
sender, oldValue, colors[role]);
164 inline void setDefaultFont(PlatformTheme *
sender,
const QFont &font)
166 if (
sender != owner || font == defaultFont) {
170 auto oldValue = defaultFont;
174 notifyWatchers<QFont>(
sender, oldValue, font);
177 inline void setSmallFont(PlatformTheme *
sender,
const QFont &font)
179 if (
sender != owner || font == smallFont) {
183 auto oldValue = smallFont;
187 notifyWatchers<QFont>(
sender, oldValue, smallFont);
190 inline void setFixedWidthFont(PlatformTheme *
sender,
const QFont &font)
192 if (
sender != owner || font == fixedWidthFont) {
196 auto oldValue = fixedWidthFont;
198 fixedWidthFont = font;
200 notifyWatchers<QFont>(
sender, oldValue, fixedWidthFont);
203 inline void addChangeWatcher(PlatformTheme *
object)
205 watchers.append(
object);
208 inline void removeChangeWatcher(PlatformTheme *
object)
210 watchers.removeOne(
object);
214 inline void notifyWatchers(PlatformTheme *
sender,
const T &oldValue,
const T &newValue)
216 for (
auto object : std::as_const(watchers)) {
217 PlatformThemeEvents::PropertyChangedEvent<T>
event(
sender, oldValue, newValue);
223 inline static void updatePalette(QPalette &palette,
const std::array<QColor, ColorRoleCount> &colors)
225 for (std::size_t i = 0; i < colors.size(); ++i) {
226 setPaletteColor(palette, ColorRole(i), colors.at(i));
231 inline static void updatePalette(QPalette &palette,
const ColorMap &colors)
233 for (
auto entry : colors) {
234 setPaletteColor(palette, ColorRole(entry.first), entry.second);
238 inline static void setPaletteColor(QPalette &palette, ColorRole role,
const QColor &color)
246 case BackgroundColor:
251 case AlternateBackgroundColor:
258 case HighlightedTextColor:
264 case VisitedLinkColor:
274class PlatformThemePrivate
277 PlatformThemePrivate()
279 , supportsIconColoring(false)
280 , pendingColorChange(false)
281 , pendingChildUpdate(false)
282 , useAlternateBackgroundColor(false)
283 , colorSet(PlatformTheme::
Window)
284 , colorGroup(PlatformTheme::Active)
288 inline QColor color(
const PlatformTheme *theme, PlatformThemeData::ColorRole color)
const
294 QColor value = data->colors.at(color);
296 if (data->owner != theme && localOverrides) {
297 auto itr = localOverrides->find(color);
298 if (itr != localOverrides->end()) {
306 inline void setColor(PlatformTheme *theme, PlatformThemeData::ColorRole color,
const QColor &value)
308 if (!localOverrides) {
309 localOverrides = std::make_unique<PlatformThemeData::ColorMap>();
314 auto itr = localOverrides->find(color);
315 if (itr != localOverrides->end()) {
316 PlatformThemeChangeTracker tracker(theme, PlatformThemeChangeTracker::PropertyChange::Color);
317 localOverrides->erase(itr);
331 auto itr = localOverrides->find(color);
332 if (itr != localOverrides->end() && itr->second == value && (data && data->owner != theme)) {
336 PlatformThemeChangeTracker tracker(theme, PlatformThemeChangeTracker::PropertyChange::Color);
338 (*localOverrides)[color] = value;
341 data->setColor(theme, color, value);
345 inline void setDataColor(PlatformTheme *theme, PlatformThemeData::ColorRole color,
const QColor &value)
351 if (localOverrides) {
352 auto itr = localOverrides->find(color);
353 if (itr != localOverrides->end()) {
358 PlatformThemeChangeTracker tracker(theme, PlatformThemeChangeTracker::PropertyChange::Color);
361 data->setColor(theme, color, value);
375 std::shared_ptr<PlatformThemeData> data;
378 std::unique_ptr<PlatformThemeData::ColorMap> localOverrides;
381 bool supportsIconColoring : 1;
382 bool pendingColorChange : 1;
383 bool pendingChildUpdate : 1;
384 bool useAlternateBackgroundColor : 1;
390 uint8_t colorSet : 4;
391 uint8_t colorGroup : 4;
395 static_assert(PlatformTheme::ColorGroupCount <= 16,
"PlatformTheme::ColorGroup contains more elements than can be stored in PlatformThemePrivate");
396 static_assert(PlatformTheme::ColorSetCount <= 16,
"PlatformTheme::ColorSet contains more elements than can be stored in PlatformThemePrivate");
398 inline static PlatformPluginFactory *s_pluginFactory =
nullptr;
401PlatformTheme::PlatformTheme(QObject *parent)
403 , d(new PlatformThemePrivate)
405 if (
QQuickItem *item = qobject_cast<QQuickItem *>(parent)) {
422PlatformTheme::~PlatformTheme()
425 d->data->removeChangeWatcher(
this);
431void PlatformTheme::setColorSet(PlatformTheme::ColorSet colorSet)
433 PlatformThemeChangeTracker tracker(
this, PlatformThemeChangeTracker::PropertyChange::ColorSet);
434 d->colorSet = colorSet;
437 d->data->setColorSet(
this, colorSet);
441PlatformTheme::ColorSet PlatformTheme::colorSet()
const
443 return d->data ? d->data->colorSet :
Window;
446void PlatformTheme::setColorGroup(PlatformTheme::ColorGroup colorGroup)
448 PlatformThemeChangeTracker tracker(
this, PlatformThemeChangeTracker::PropertyChange::ColorGroup);
449 d->colorGroup = colorGroup;
452 d->data->setColorGroup(
this, colorGroup);
456PlatformTheme::ColorGroup PlatformTheme::colorGroup()
const
458 return d->data ? d->data->colorGroup : Active;
461bool PlatformTheme::inherit()
const
466void PlatformTheme::setInherit(
bool inherit)
468 if (inherit == d->inherit) {
472 d->inherit = inherit;
475 Q_EMIT inheritChanged(inherit);
478QColor PlatformTheme::textColor()
const
480 return d->color(
this, PlatformThemeData::TextColor);
483QColor PlatformTheme::disabledTextColor()
const
485 return d->color(
this, PlatformThemeData::DisabledTextColor);
488QColor PlatformTheme::highlightColor()
const
490 return d->color(
this, PlatformThemeData::HighlightColor);
493QColor PlatformTheme::highlightedTextColor()
const
495 return d->color(
this, PlatformThemeData::HighlightedTextColor);
498QColor PlatformTheme::backgroundColor()
const
500 return d->color(
this, PlatformThemeData::BackgroundColor);
503QColor PlatformTheme::alternateBackgroundColor()
const
505 return d->color(
this, PlatformThemeData::AlternateBackgroundColor);
508QColor PlatformTheme::activeTextColor()
const
510 return d->color(
this, PlatformThemeData::ActiveTextColor);
513QColor PlatformTheme::activeBackgroundColor()
const
515 return d->color(
this, PlatformThemeData::ActiveBackgroundColor);
518QColor PlatformTheme::linkColor()
const
520 return d->color(
this, PlatformThemeData::LinkColor);
523QColor PlatformTheme::linkBackgroundColor()
const
525 return d->color(
this, PlatformThemeData::LinkBackgroundColor);
528QColor PlatformTheme::visitedLinkColor()
const
530 return d->color(
this, PlatformThemeData::VisitedLinkColor);
533QColor PlatformTheme::visitedLinkBackgroundColor()
const
535 return d->color(
this, PlatformThemeData::VisitedLinkBackgroundColor);
538QColor PlatformTheme::negativeTextColor()
const
540 return d->color(
this, PlatformThemeData::NegativeTextColor);
543QColor PlatformTheme::negativeBackgroundColor()
const
545 return d->color(
this, PlatformThemeData::NegativeBackgroundColor);
548QColor PlatformTheme::neutralTextColor()
const
550 return d->color(
this, PlatformThemeData::NeutralTextColor);
553QColor PlatformTheme::neutralBackgroundColor()
const
555 return d->color(
this, PlatformThemeData::NeutralBackgroundColor);
558QColor PlatformTheme::positiveTextColor()
const
560 return d->color(
this, PlatformThemeData::PositiveTextColor);
563QColor PlatformTheme::positiveBackgroundColor()
const
565 return d->color(
this, PlatformThemeData::PositiveBackgroundColor);
568QColor PlatformTheme::focusColor()
const
570 return d->color(
this, PlatformThemeData::FocusColor);
573QColor PlatformTheme::hoverColor()
const
575 return d->color(
this, PlatformThemeData::HoverColor);
579void PlatformTheme::setTextColor(
const QColor &color)
581 d->setDataColor(
this, PlatformThemeData::TextColor, color);
584void PlatformTheme::setDisabledTextColor(
const QColor &color)
586 d->setDataColor(
this, PlatformThemeData::DisabledTextColor, color);
589void PlatformTheme::setBackgroundColor(
const QColor &color)
591 d->setDataColor(
this, PlatformThemeData::BackgroundColor, color);
594void PlatformTheme::setAlternateBackgroundColor(
const QColor &color)
596 d->setDataColor(
this, PlatformThemeData::AlternateBackgroundColor, color);
599void PlatformTheme::setHighlightColor(
const QColor &color)
601 d->setDataColor(
this, PlatformThemeData::HighlightColor, color);
604void PlatformTheme::setHighlightedTextColor(
const QColor &color)
606 d->setDataColor(
this, PlatformThemeData::HighlightedTextColor, color);
609void PlatformTheme::setActiveTextColor(
const QColor &color)
611 d->setDataColor(
this, PlatformThemeData::ActiveTextColor, color);
614void PlatformTheme::setActiveBackgroundColor(
const QColor &color)
616 d->setDataColor(
this, PlatformThemeData::ActiveBackgroundColor, color);
619void PlatformTheme::setLinkColor(
const QColor &color)
621 d->setDataColor(
this, PlatformThemeData::LinkColor, color);
624void PlatformTheme::setLinkBackgroundColor(
const QColor &color)
626 d->setDataColor(
this, PlatformThemeData::LinkBackgroundColor, color);
629void PlatformTheme::setVisitedLinkColor(
const QColor &color)
631 d->setDataColor(
this, PlatformThemeData::VisitedLinkColor, color);
634void PlatformTheme::setVisitedLinkBackgroundColor(
const QColor &color)
636 d->setDataColor(
this, PlatformThemeData::VisitedLinkBackgroundColor, color);
639void PlatformTheme::setNegativeTextColor(
const QColor &color)
641 d->setDataColor(
this, PlatformThemeData::NegativeTextColor, color);
644void PlatformTheme::setNegativeBackgroundColor(
const QColor &color)
646 d->setDataColor(
this, PlatformThemeData::NegativeBackgroundColor, color);
649void PlatformTheme::setNeutralTextColor(
const QColor &color)
651 d->setDataColor(
this, PlatformThemeData::NeutralTextColor, color);
654void PlatformTheme::setNeutralBackgroundColor(
const QColor &color)
656 d->setDataColor(
this, PlatformThemeData::NeutralBackgroundColor, color);
659void PlatformTheme::setPositiveTextColor(
const QColor &color)
661 d->setDataColor(
this, PlatformThemeData::PositiveTextColor, color);
664void PlatformTheme::setPositiveBackgroundColor(
const QColor &color)
666 d->setDataColor(
this, PlatformThemeData::PositiveBackgroundColor, color);
669void PlatformTheme::setHoverColor(
const QColor &color)
671 d->setDataColor(
this, PlatformThemeData::HoverColor, color);
674void PlatformTheme::setFocusColor(
const QColor &color)
676 d->setDataColor(
this, PlatformThemeData::FocusColor, color);
679QFont PlatformTheme::defaultFont()
const
681 return d->data ? d->data->defaultFont :
QFont{};
684void PlatformTheme::setDefaultFont(
const QFont &font)
686 PlatformThemeChangeTracker tracker(
this, PlatformThemeChangeTracker::PropertyChange::Font);
688 d->data->setDefaultFont(
this, font);
692QFont PlatformTheme::smallFont()
const
694 return d->data ? d->data->smallFont :
QFont{};
697void PlatformTheme::setSmallFont(
const QFont &font)
699 PlatformThemeChangeTracker tracker(
this, PlatformThemeChangeTracker::PropertyChange::Font);
701 d->data->setSmallFont(
this, font);
705QFont PlatformTheme::fixedWidthFont()
const
707 return d->data ? d->data->fixedWidthFont :
QFont{};
710void PlatformTheme::setFixedWidthFont(
const QFont &font)
712 PlatformThemeChangeTracker tracker(
this, PlatformThemeChangeTracker::PropertyChange::Font);
714 d->data->setFixedWidthFont(
this, font);
718qreal PlatformTheme::frameContrast()
const
726qreal PlatformTheme::lightFrameContrast()
const
730 return frameContrast() / 2.0;
734void PlatformTheme::setCustomTextColor(
const QColor &color)
736 d->setColor(
this, PlatformThemeData::TextColor, color);
739void PlatformTheme::setCustomDisabledTextColor(
const QColor &color)
741 d->setColor(
this, PlatformThemeData::DisabledTextColor, color);
744void PlatformTheme::setCustomBackgroundColor(
const QColor &color)
746 d->setColor(
this, PlatformThemeData::BackgroundColor, color);
749void PlatformTheme::setCustomAlternateBackgroundColor(
const QColor &color)
751 d->setColor(
this, PlatformThemeData::AlternateBackgroundColor, color);
754void PlatformTheme::setCustomHighlightColor(
const QColor &color)
756 d->setColor(
this, PlatformThemeData::HighlightColor, color);
759void PlatformTheme::setCustomHighlightedTextColor(
const QColor &color)
761 d->setColor(
this, PlatformThemeData::HighlightedTextColor, color);
764void PlatformTheme::setCustomActiveTextColor(
const QColor &color)
766 d->setColor(
this, PlatformThemeData::ActiveTextColor, color);
769void PlatformTheme::setCustomActiveBackgroundColor(
const QColor &color)
771 d->setColor(
this, PlatformThemeData::ActiveBackgroundColor, color);
774void PlatformTheme::setCustomLinkColor(
const QColor &color)
776 d->setColor(
this, PlatformThemeData::LinkColor, color);
779void PlatformTheme::setCustomLinkBackgroundColor(
const QColor &color)
781 d->setColor(
this, PlatformThemeData::LinkBackgroundColor, color);
784void PlatformTheme::setCustomVisitedLinkColor(
const QColor &color)
786 d->setColor(
this, PlatformThemeData::TextColor, color);
789void PlatformTheme::setCustomVisitedLinkBackgroundColor(
const QColor &color)
791 d->setColor(
this, PlatformThemeData::VisitedLinkBackgroundColor, color);
794void PlatformTheme::setCustomNegativeTextColor(
const QColor &color)
796 d->setColor(
this, PlatformThemeData::NegativeTextColor, color);
799void PlatformTheme::setCustomNegativeBackgroundColor(
const QColor &color)
801 d->setColor(
this, PlatformThemeData::NegativeBackgroundColor, color);
804void PlatformTheme::setCustomNeutralTextColor(
const QColor &color)
806 d->setColor(
this, PlatformThemeData::NeutralTextColor, color);
809void PlatformTheme::setCustomNeutralBackgroundColor(
const QColor &color)
811 d->setColor(
this, PlatformThemeData::NeutralBackgroundColor, color);
814void PlatformTheme::setCustomPositiveTextColor(
const QColor &color)
816 d->setColor(
this, PlatformThemeData::PositiveTextColor, color);
819void PlatformTheme::setCustomPositiveBackgroundColor(
const QColor &color)
821 d->setColor(
this, PlatformThemeData::PositiveBackgroundColor, color);
824void PlatformTheme::setCustomHoverColor(
const QColor &color)
826 d->setColor(
this, PlatformThemeData::HoverColor, color);
829void PlatformTheme::setCustomFocusColor(
const QColor &color)
831 d->setColor(
this, PlatformThemeData::FocusColor, color);
834bool PlatformTheme::useAlternateBackgroundColor()
const
836 return d->useAlternateBackgroundColor;
839void PlatformTheme::setUseAlternateBackgroundColor(
bool alternate)
841 if (alternate == d->useAlternateBackgroundColor) {
845 d->useAlternateBackgroundColor = alternate;
846 Q_EMIT useAlternateBackgroundColorChanged(alternate);
849QPalette PlatformTheme::palette()
const
855 auto palette = d->data->palette;
857 if (d->localOverrides) {
858 PlatformThemeData::updatePalette(palette, *d->localOverrides);
866 Q_UNUSED(customColor);
871bool PlatformTheme::supportsIconColoring()
const
873 return d->supportsIconColoring;
876void PlatformTheme::setSupportsIconColoring(
bool support)
878 d->supportsIconColoring = support;
881PlatformTheme *PlatformTheme::qmlAttachedProperties(
QObject *
object)
890 auto plugin = PlatformPluginFactory::findPlugin(pluginName);
891 if (!plugin && !pluginName.
isEmpty()) {
892 plugin = PlatformPluginFactory::findPlugin();
896 if (
auto theme = plugin->createPlatformTheme(
object)) {
901 return new BasicTheme(
object);
904void PlatformTheme::emitSignalsForChanges(
int changes)
910 auto propertyChanges = PlatformThemeChangeTracker::PropertyChanges::fromInt(changes);
912 if (propertyChanges & PlatformThemeChangeTracker::PropertyChange::ColorSet) {
913 Q_EMIT colorSetChanged(ColorSet(d->data->colorSet));
916 if (propertyChanges & PlatformThemeChangeTracker::PropertyChange::ColorGroup) {
917 Q_EMIT colorGroupChanged(ColorGroup(d->data->colorGroup));
920 if (propertyChanges & PlatformThemeChangeTracker::PropertyChange::Color) {
921 Q_EMIT colorsChanged();
924 if (propertyChanges & PlatformThemeChangeTracker::PropertyChange::Palette) {
925 Q_EMIT paletteChanged(d->data->palette);
928 if (propertyChanges & PlatformThemeChangeTracker::PropertyChange::Font) {
929 Q_EMIT defaultFontChanged(d->data->defaultFont);
930 Q_EMIT smallFontChanged(d->data->smallFont);
931 Q_EMIT fixedWidthFontChanged(d->data->fixedWidthFont);
934 if (propertyChanges & PlatformThemeChangeTracker::PropertyChange::Data) {
935 updateChildren(parent());
939bool PlatformTheme::event(
QEvent *event)
941 PlatformThemeChangeTracker tracker(
this);
943 if (
event->type() == PlatformThemeEvents::DataChangedEvent::type) {
944 auto changeEvent =
static_cast<PlatformThemeEvents::DataChangedEvent *
>(
event);
946 if (changeEvent->sender !=
this) {
950 if (changeEvent->oldValue) {
951 changeEvent->oldValue->removeChangeWatcher(
this);
954 if (changeEvent->newValue) {
955 auto data = changeEvent->newValue;
956 data->addChangeWatcher(
this);
959 tracker.markDirty(PlatformThemeChangeTracker::PropertyChange::All);
963 if (
event->type() == PlatformThemeEvents::ColorSetChangedEvent::type) {
964 tracker.markDirty(PlatformThemeChangeTracker::PropertyChange::ColorSet);
968 if (
event->type() == PlatformThemeEvents::ColorGroupChangedEvent::type) {
969 tracker.markDirty(PlatformThemeChangeTracker::PropertyChange::ColorGroup);
973 if (
event->type() == PlatformThemeEvents::ColorChangedEvent::type) {
974 tracker.markDirty(PlatformThemeChangeTracker::PropertyChange::Color | PlatformThemeChangeTracker::PropertyChange::Palette);
978 if (
event->type() == PlatformThemeEvents::FontChangedEvent::type) {
979 tracker.markDirty(PlatformThemeChangeTracker::PropertyChange::Font);
986void PlatformTheme::update()
988 auto oldData = d->data;
990 bool actualInherit = d->inherit;
991 if (
QQuickItem *item = qobject_cast<QQuickItem *>(parent())) {
993 if (colorGroup() != Disabled && !item->isEnabled()) {
994 actualInherit =
false;
1001 candidate = determineParent(candidate);
1006 auto t =
static_cast<PlatformTheme *
>(qmlAttachedPropertiesObject<PlatformTheme>(candidate,
false));
1007 if (t && t->d->data && t->d->data->owner == t) {
1008 if (d->data == t->d->data) {
1013 d->data = t->d->data;
1015 PlatformThemeEvents::DataChangedEvent
event{
this, oldData, t->d->data};
1021 }
else if (d->data && d->data->owner !=
this) {
1028 d->data = std::make_shared<PlatformThemeData>();
1029 d->data->owner =
this;
1031 d->data->setColorSet(
this,
static_cast<ColorSet
>(d->colorSet));
1032 d->data->setColorGroup(
this,
static_cast<ColorGroup
>(d->colorGroup));
1037 if (d->inherit && !actualInherit && oldData) {
1038 d->data->setColorSet(
this, oldData->colorSet);
1042 if (d->localOverrides) {
1043 for (
auto entry : *d->localOverrides) {
1044 d->data->setColor(
this, PlatformThemeData::ColorRole(entry.first), entry.second);
1048 PlatformThemeEvents::DataChangedEvent
event{
this, oldData, d->data};
1052void PlatformTheme::updateChildren(
QObject *
object)
1058 const auto children =
object->children();
1059 for (
auto child : children) {
1060 auto t =
static_cast<PlatformTheme *
>(qmlAttachedPropertiesObject<PlatformTheme>(child,
false));
1064 updateChildren(child);
1078 auto item = qobject_cast<QQuickItem *>(
object);
1080 return item->parentItem();
1082 return object->parent();
1086PlatformThemeChangeTracker::PlatformThemeChangeTracker(PlatformTheme *theme, PropertyChanges changes)
1089 auto itr = s_blockedChanges.constFind(theme);
1090 if (itr == s_blockedChanges.constEnd() || (*itr).expired()) {
1091 m_data = std::make_shared<Data>();
1092 s_blockedChanges.insert(theme, m_data);
1094 m_data = (*itr).lock();
1097 m_data->changes |= changes;
1100PlatformThemeChangeTracker::~PlatformThemeChangeTracker() noexcept
1102 std::weak_ptr<Data> dataWatcher = m_data;
1104 auto changes = m_data->changes;
1107 if (dataWatcher.use_count() <= 0) {
1108 m_theme->emitSignalsForChanges(changes);
1109 s_blockedChanges.remove(m_theme);
1113void PlatformThemeChangeTracker::markDirty(PropertyChanges changes)
1115 m_data->changes |= changes;
1120#include "moc_platformtheme.cpp"
1121#include "platformtheme.moc"
AKONADI_CALENDAR_EXPORT KCalendarCore::Event::Ptr event(const Akonadi::Item &item)
void update(Part *part, const QByteArray &data, qint64 dataSize)
bool isValid() const const
bool sendEvent(QObject *receiver, QEvent *event)
int registerEventType(int hint)
QFont systemFont(SystemFont type)
QIcon fromTheme(const QString &name)
virtual bool event(QEvent *e)
QVariant property(const char *name) const const
QObject * sender() const const
void parentChanged(QQuickItem *)
void windowChanged(QQuickWindow *window)
bool isEmpty() const const
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
QString toString() const const