Skip to content
  • 0 Votes
    2 Posts
    409 Views
    bibasmallB

    I have found out that this problem is mainly related to WinAPI + framelessness, not to Qt. I didn't manage to find any working WinAPI solution, for example, I've tried this one: melak47's solution. So I've chosen Qt way. This approach is not as concise as I expected from the WinAPI approach, but it works.
    Here is a code snippet describing only the necessary parts.

    .hpp

    class FramelessWindow : public QQuickWindow { Q_OBJECT QML_ELEMENT Q_PROPERTY(bool isMaximized READ isMaximized NOTIFY isMaximizedChanged) signals: void isMaximizedChanged(); public: FramelessWindow() noexcept; Q_INVOKABLE void showNormal() noexcept; Q_INVOKABLE void showMaximized() noexcept; bool isMaximized() const noexcept; private: bool eventFilter(QObject* watched, QEvent* event) override; bool nativeEvent(const QByteArray& eventType, void* message, qintptr* result) override; QRect restoredGeometry_; bool isMaximized_; };

    .cpp

    FramelessWindow::FramelessWindow() noexcept : isMaximized_ { false } { setFlags(Qt::Window | Qt::FramelessWindowHint | Qt::WindowSystemMenuHint | Qt::WindowMaximizeButtonHint); installEventFilter(this); SetWindowLongPtr((HWND)winId(), GWL_STYLE, WS_POPUP | WS_THICKFRAME | WS_CAPTION | WS_SYSMENU | WS_MAXIMIZEBOX | WS_MINIMIZEBOX); } void FramelessWindow::showNormal() noexcept { setGeometry(restoredGeometry_); isMaximized_ = false; emit isMaximizedChanged(); } void FramelessWindow::showMaximized() noexcept { restoredGeometry_ = geometry(); setGeometry(screen()->availableGeometry()); isMaximized_ = true; emit isMaximizedChanged(); } bool FramelessWindow::isMaximized() const noexcept { return isMaximized_; } bool FramelessWindow::eventFilter(QObject* watched, QEvent* event) { QPoint cursorPos = QCursor::pos(); qreal dpr = devicePixelRatio(); QRect draggingArea = geometry(); draggingArea.setHeight(32 * dpr); draggingArea.setY(draggingArea.y() + dpr * ResizeBorderWidth); if (draggingArea.contains(cursorPos)) { if (event->type() == QEvent::MouseButtonPress) { if (isMaximized_) { restoredGeometry_.moveTo({ QCursor::pos().x() - restoredGeometry_.width() / 2, QCursor::pos().y() - 10 }); showNormal(); } startSystemMove(); return true; } else if (isResizable_ && event->type() == QEvent::MouseButtonDblClick) { if (draggingArea.contains(cursorPos)) { if (isMaximized_) { showNormal(); } else { showMaximized(); } return true; } } else if (event->type() == QEvent::WindowStateChange && QWindow::visibility() == QWindow::Maximized) { setGeometry(screen()->availableGeometry()); isMaximized_ = true; emit isMaximizedChanged(); return true; } } return QQuickWindow::eventFilter(watched, event); } bool FramelessWindow::nativeEvent(const QByteArray& eventType, void* message, qintptr* result) { if (auto* msg = static_cast<MSG*>(message); msg->message == WM_NCCALCSIZE) { NCCALCSIZE_PARAMS& params = *reinterpret_cast<NCCALCSIZE_PARAMS*>(msg->lParam); if (params.rgrc[0].top != 0) { --params.rgrc[0].top; } *result = 0; return true; } return QQuickWindow::nativeEvent(eventType, message, result); }
  • 0 Votes
    4 Posts
    570 Views
    Pl45m4P

    @StudentScripter

    This?

    WindowSplit.png

    It's called Split Window / Window Tile or something like that and is a Window Manager functionality (in your case, X on Windows 7/10).
    Because frameless Qt toplevel Widgets don't request a Window decoration, I think X does not recognize that you want to snap/split it anyway.
    This is probably not doable with Qt only and platform/Window Manager dependent, maybe you need some extension. Haven't found one though.

    Edit:
    If you are fine with not using the native functionality, you could try to implement something like that using your Qt widget... when enabled, calculate the requested area (1/2, 1/4...) of your screen size and geometry and resize + move your widget accordingly.

  • 0 Votes
    5 Posts
    461 Views
    S

    @Pl45m4 Well thank you very much that does the job! Is there any way to make these menu items background heigher without changing the font size.

    EDIT:
    QMenuBar{
    min-height: 20px;
    }

  • 0 Votes
    3 Posts
    386 Views
    A

    @AlexZhZZ
    See QTBUG-120196

  • 0 Votes
    3 Posts
    364 Views
    bibasmallB

    The problem was that every child widget of the native widnow got it's own window descriptor (HWND), so, for example, if I hit the menubar, in nativeEvent I saw that the message had a different descriptor than the main window had.
    This is what solved my problem:

    QApplication a(argc, argv); a.setAttribute(Qt::AA_DontCreateNativeWidgetSiblings); //... CEventFilter e{ &w }; a.installNativeEventFilter(&e);
  • 1 Votes
    1 Posts
    399 Views
    No one has replied
  • 0 Votes
    3 Posts
    645 Views
    T

    @mcf1lmnfs No, because title bar is not a Qt element, is system made, so I cannot change it via Qt Style Sheets.

  • 0 Votes
    2 Posts
    621 Views
    SGaistS

    Hi,

    An educated guess is that the second case is handled by the window manager (the decoration is not done by Qt).

    One possible thing to do would be to check the screen resolution in your method and try to adapt to that.

  • 0 Votes
    4 Posts
    1k Views
    M

    @Manifolds

    SOLVED

  • 0 Votes
    7 Posts
    5k Views
    IMAN4KI

    Ok.
    It might get better in the future !

    If you wan to get ride of QGraphicsDropShadowEffect :

    void drawShadow(QPainter &_painter, qint16 _margin, qreal _radius, QColor _start, QColor _end, qreal _startPosition, qreal _endPosition0, qreal _endPosition1, qreal _width, qreal _height) { _painter.setPen(Qt::NoPen); QLinearGradient gradient; gradient.setColorAt(_startPosition, _start); gradient.setColorAt(_endPosition0, _end); // Right QPointF right0(_width - _margin, _height / 2); QPointF right1(_width, _height / 2); gradient.setStart(right0); gradient.setFinalStop(right1); _painter.setBrush(QBrush(gradient)); _painter.drawRoundRect(QRectF(QPointF(_width - _margin*_radius, _margin), QPointF(_width, _height - _margin)), 0.0, 0.0); // Left QPointF left0(_margin, _height / 2); QPointF left1(0, _height / 2); gradient.setStart(left0); gradient.setFinalStop(left1); _painter.setBrush(QBrush(gradient)); _painter.drawRoundRect(QRectF(QPointF(_margin *_radius, _margin), QPointF(0, _height - _margin)), 0.0, 0.0); // Top QPointF top0(_width / 2, _margin); QPointF top1(_width / 2, 0); gradient.setStart(top0); gradient.setFinalStop(top1); _painter.setBrush(QBrush(gradient)); _painter.drawRoundRect(QRectF(QPointF(_width - _margin, 0), QPointF(_margin, _margin)), 0.0, 0.0); // Bottom QPointF bottom0(_width / 2, _height - _margin); QPointF bottom1(_width / 2, _height); gradient.setStart(bottom0); gradient.setFinalStop(bottom1); _painter.setBrush(QBrush(gradient)); _painter.drawRoundRect(QRectF(QPointF(_margin, _height - _margin), QPointF(_width - _margin, _height)), 0.0, 0.0); // BottomRight QPointF bottomright0(_width - _margin, _height - _margin); QPointF bottomright1(_width, _height); gradient.setStart(bottomright0); gradient.setFinalStop(bottomright1); gradient.setColorAt(_endPosition1, _end); _painter.setBrush(QBrush(gradient)); _painter.drawRoundRect(QRectF(bottomright0, bottomright1), 0.0, 0.0); // BottomLeft QPointF bottomleft0(_margin, _height - _margin); QPointF bottomleft1(0, _height); gradient.setStart(bottomleft0); gradient.setFinalStop(bottomleft1); gradient.setColorAt(_endPosition1, _end); _painter.setBrush(QBrush(gradient)); _painter.drawRoundRect(QRectF(bottomleft0, bottomleft1), 0.0, 0.0); // TopLeft QPointF topleft0(_margin, _margin); QPointF topleft1(0, 0); gradient.setStart(topleft0); gradient.setFinalStop(topleft1); gradient.setColorAt(_endPosition1, _end); _painter.setBrush(QBrush(gradient)); _painter.drawRoundRect(QRectF(topleft0, topleft1), 0.0, 0.0); // TopRight QPointF topright0(_width - _margin, _margin); QPointF topright1(_width, 0); gradient.setStart(topright0); gradient.setFinalStop(topright1); gradient.setColorAt(_endPosition1, _end); _painter.setBrush(QBrush(gradient)); _painter.drawRoundRect(QRectF(topright0, topright1), 0.0, 0.0); // Widget _painter.setBrush(QBrush("#FFFFFF")); _painter.setRenderHint(QPainter::Antialiasing); _painter.drawRoundRect(QRectF(QPointF(_margin, _margin), QPointF(_width - _margin, _height - _margin)), _radius, _radius); }

    drawShadow(painter, 10, 2.0, QColor(120, 120, 120, 32), QColor(255, 255, 255, 0), 0.0, 1.0, 0.6, width(), height());
    don't forget setAttribute(Qt::WA_TranslucentBackground);
    Final Resualt : https://onedrive.live.com/?cid=8882d1e3bc0f61ab&id=8882D1E3BC0F61AB!7415&authkey=!AH66ZieCJDqvXhk

  • 0 Votes
    24 Posts
    9k Views
    V

    Hello!

    I faced a similar problem, tried hacks with single QTimer and showEvent: timer was a solution, and showEvent -- wasn't. I also use Win10, but Qt5.5.1. Have you succeeded?