stdware / qwindowkit

Cross-platform frameless window framework for Qt. Support Windows, macOS, Linux.
Apache License 2.0
538 stars 85 forks source link

QDialog不会显示标题栏 #109

Closed neomissing closed 3 months ago

neomissing commented 3 months ago

FramelessDialog::FramelessDialog(QWidget *parent) : QDialog(parent) { installWindowAgent(); setWindowTitle(tr("Dialog")); // resize(800, 600); }

static inline void emulateLeaveEvent(QWidget *widget) { Q_ASSERT(widget); if (!widget) { return; } QTimer::singleShot(0, widget, [widget]() {

if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))

    const QScreen *screen = widget->screen();

else

    const QScreen *screen = widget->windowHandle()->screen();

endif

    const QPoint globalPos = QCursor::pos(screen);
    if (!QRect(widget->mapToGlobal(QPoint{0, 0}), widget->size()).contains(globalPos)) {
        QCoreApplication::postEvent(widget, new QEvent(QEvent::Leave));
        if (widget->testAttribute(Qt::WA_Hover)) {
            const QPoint localPos = widget->mapFromGlobal(globalPos);
            const QPoint scenePos = widget->window()->mapFromGlobal(globalPos);
            static constexpr const auto oldPos = QPoint{};
            const Qt::KeyboardModifiers modifiers = QGuiApplication::keyboardModifiers();

if (QT_VERSION >= QT_VERSION_CHECK(6, 4, 0))

            const auto event = new QHoverEvent(QEvent::HoverLeave,
                                               scenePos,
                                               globalPos,
                                               oldPos,
                                               modifiers);
            Q_UNUSED(localPos);

elif (QT_VERSION >= QT_VERSION_CHECK(6, 3, 0))

            const auto event =  new QHoverEvent(QEvent::HoverLeave, localPos, globalPos, oldPos, modifiers);
            Q_UNUSED(scenePos);

else

            const auto event =  new QHoverEvent(QEvent::HoverLeave, localPos, oldPos, modifiers);
            Q_UNUSED(scenePos);

endif

            QCoreApplication::postEvent(widget, event);
        }
    }
});

}

void FramelessDialog::closeEvent(QCloseEvent *event) { event->accept(); }

void FramelessDialog::installWindowAgent() { windowAgent = new QWK::WidgetWindowAgent(this); windowAgent->setup(this);

auto menuBar = new QMenuBar();
menuBar->setObjectName(QStringLiteral("win-menu-bar"));

auto titleLabel = new QLabel();
titleLabel->setAlignment(Qt::AlignCenter);
titleLabel->setObjectName(QStringLiteral("win-title-label"));

ifndef Q_OS_MAC

auto iconButton = new QWK::WindowButton();
iconButton->setObjectName(QStringLiteral("icon-button"));
iconButton->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);

auto minButton = new QWK::WindowButton();
minButton->setObjectName(QStringLiteral("min-button"));
minButton->setProperty("system-button", true);
minButton->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);

auto maxButton = new QWK::WindowButton();
maxButton->setCheckable(true);
maxButton->setObjectName(QStringLiteral("max-button"));
maxButton->setProperty("system-button", true);
maxButton->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);

auto closeButton = new QWK::WindowButton();
closeButton->setObjectName(QStringLiteral("close-button"));
closeButton->setProperty("system-button", true);
closeButton->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);

endif

auto windowBar = new QWK::WindowBar();

ifndef Q_OS_MAC

windowBar->setIconButton(iconButton);
windowBar->setMinButton(minButton);
windowBar->setMaxButton(maxButton);
windowBar->setCloseButton(closeButton);

endif

windowBar->setMenuBar(menuBar);
windowBar->setTitleLabel(titleLabel);
windowBar->setHostWidget(this);

windowAgent->setTitleBar(windowBar);

ifndef Q_OS_MAC

windowAgent->setSystemButton(QWK::WindowAgentBase::WindowIcon, iconButton);
windowAgent->setSystemButton(QWK::WindowAgentBase::Minimize, minButton);
windowAgent->setSystemButton(QWK::WindowAgentBase::Maximize, maxButton);
windowAgent->setSystemButton(QWK::WindowAgentBase::Close, closeButton);

endif

windowAgent->setHitTestVisible(menuBar, true);

ifdef Q_OS_MAC

windowAgent->setSystemButtonAreaCallback([](const QSize &size) {
    static constexpr const int width = 75;
    return QRect(QPoint(size.width() - width, 0), QSize(width, size.height())); //
});

endif

ifndef Q_OS_MAC

connect(windowBar, &QWK::WindowBar::minimizeRequested, this, &QWidget::showMinimized);
connect(windowBar, &QWK::WindowBar::maximizeRequested, this, [this, maxButton](bool max) {
    if (max) {
        showMaximized();
    } else {
        showNormal();
    }

    // It's a Qt issue that if a QAbstractButton::clicked triggers a window's maximization,
    // the button remains to be hovered until the mouse move. As a result, we need to
    // manually send leave events to the button.
    emulateLeaveEvent(maxButton);
});
connect(windowBar, &QWK::WindowBar::closeRequested, this, &QWidget::close);

endif

}