1. 程式人生 > >QT自定義視窗標題欄實現拖動雙擊放大縮小

QT自定義視窗標題欄實現拖動雙擊放大縮小

    去掉Qt視窗的標題邊框,重新定義標題欄,可以在標題欄上實現更多的功能,能滿足更多的開發需求,可以實現標題欄的拖動,雙擊,自定義放大縮小。

     本文引用自:http://www.devbean.net/2011/10/custom-qt-titlebar/,感謝原作者,本文對其進行了重新整理,並且修改了一些小問題。

    執行介面如下:


    詳細程式碼如下:

#include <QWidget>
#include <QToolButton>
#include <QPixmap>

class XMainWindowTitle : public QWidget
{
    Q_OBJECT
public:
    XMainWindowTitle(QWidget *parent);

public slots:
    void showSmall();

    void showMaxRestore();

protected:
    void mousePressEvent(QMouseEvent *e);
    void mouseMoveEvent(QMouseEvent *e);
    void mouseDoubleClickEvent(QMouseEvent *e);

private:
    QToolButton *minimize;
    QToolButton *maximize;
    QToolButton *close;
    QPixmap restorePix, maxPix;
    bool maxNormal;
    QPoint startPos;
    QPoint clickPos;
};
#include "XMainWindowTitle.h"
#include <QHBoxLayout>
#include <QMouseEvent>
#include <QStyle>
#include <QLabel>

XMainWindowTitle::XMainWindowTitle(QWidget *parent)
{
    // 不繼承父元件的背景色
    setAutoFillBackground(true);
    // 使用 Highlight 作為背景色
    setBackgroundRole(QPalette::Highlight);

    minimize = new QToolButton(this);
    maximize = new QToolButton(this);
    close= new QToolButton(this);

    QPixmap pix = style()->standardPixmap(QStyle::SP_TitleBarCloseButton);
    close->setIcon(pix);
    close->setToolTip("close");
    close->setStyleSheet("QToolButton:hover{background-color:rgb(219,75,75);}");

    maxPix = style()->standardPixmap(QStyle::SP_TitleBarMaxButton);
    maximize->setIcon(maxPix);
    maximize->setToolTip("restore");

    pix = style()->standardPixmap(QStyle::SP_TitleBarMinButton);
    minimize->setIcon(pix);
    minimize->setToolTip("minsize");

    restorePix = style()->standardPixmap(QStyle::SP_TitleBarNormalButton);

    minimize->setMinimumSize(30,25);
    close->setMinimumSize(30,25);
    maximize->setMinimumSize(30,25);

    QLabel *label = new QLabel(this);
    label->setText("Window Title");
    parent->setWindowTitle("Window Title");

    QHBoxLayout *hbox = new QHBoxLayout(this);

    hbox->addWidget(label);
    hbox->addWidget(minimize);
    hbox->addWidget(maximize);
    hbox->addWidget(close);

    hbox->insertStretch(1, 500);
    hbox->setSpacing(0);
    setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);

    maxNormal = false;

    connect(close, SIGNAL( clicked() ), parent, SLOT(close() ) );
    connect(minimize, SIGNAL( clicked() ), this, SLOT(showSmall() ) );
    connect(maximize, SIGNAL( clicked() ), this, SLOT(showMaxRestore() ) );
}

void XMainWindowTitle::showSmall()
{
    parentWidget()->showMinimized();
}

void XMainWindowTitle::showMaxRestore()
{
    if (maxNormal) {
        parentWidget()->showNormal();
        maxNormal = !maxNormal;
        maximize->setIcon(maxPix);
    } else {
        parentWidget()->showMaximized();
        maxNormal = !maxNormal;
        maximize->setIcon(restorePix);
    }
}

void XMainWindowTitle::mousePressEvent(QMouseEvent *e)
{
    startPos = e->globalPos();
    clickPos = mapToParent(e->pos());
}
void XMainWindowTitle::mouseMoveEvent(QMouseEvent *e)
{
    if (maxNormal)
        return;
    parentWidget()->move(e->globalPos() - clickPos);
}

void XMainWindowTitle::mouseDoubleClickEvent(QMouseEvent *e)
{
    if(e->button() == Qt::LeftButton)
    {
        showMaxRestore();
    }
}

#include "XMainWindowTitle.h"
#include <QFrame>

class XMainWindow : public QFrame
{
public:

    XMainWindow();

    // 通過 getter 允許外界訪問 frame 的 content 區域
    // 其它子元件應該新增到這裡
    QWidget *contentWidget() const ;

    XMainWindowTitle *mainWindowTitle() const ;

protected:
    void mousePressEvent(QMouseEvent *e);

    void mouseMoveEvent(QMouseEvent *e);

    void mouseReleaseEvent(QMouseEvent *e);

private:
    XMainWindowTitle *titleBar;
    QWidget *content;
    QPoint oldPos;
    bool mouseDown;
    bool left, right, bottom;
};
#include "XMainWindow.h"
#include <QVBoxLayout>
#include <QMouseEvent>
#include <QDebug>

XMainWindow::XMainWindow()
{
    mouseDown = false;
    setFrameShape(Panel);

    setWindowFlags(Qt::FramelessWindowHint);
    setMouseTracking(true);

    titleBar = new XMainWindowTitle(this);
    titleBar->setCursor(Qt::ArrowCursor);

    content = new QWidget(this);

    content->setMouseTracking(true);
    QVBoxLayout *vbox = new QVBoxLayout(this);
    vbox->addWidget(titleBar);
    vbox->setContentsMargins(0,0,0,0);
    vbox->setSpacing(0);

    QVBoxLayout *layout = new QVBoxLayout;
    layout->addWidget(content);
    layout->setContentsMargins(5,5,5,5);
    layout->setSpacing(0);
    vbox->addLayout(layout);
}

QWidget *XMainWindow::contentWidget() const { return content; }

XMainWindowTitle *XMainWindow::mainWindowTitle() const { return titleBar; }

void XMainWindow::mousePressEvent(QMouseEvent *e)
{
    oldPos = e->pos();
    mouseDown = e->button() == Qt::LeftButton;
}

void XMainWindow::mouseMoveEvent(QMouseEvent *e)
{
    int x = e->x();
    int y = e->y();

    if (mouseDown) {
        int dx = x - oldPos.x();
        int dy = y - oldPos.y();

        QRect g = geometry();

        if (left)
            g.setLeft(g.left() + dx);
        if (right)
            g.setRight(g.right() + dx);
        if (bottom)
            g.setBottom(g.bottom() + dy);

        setGeometry(g);

        oldPos = QPoint(!left ? e->x() : oldPos.x(), e->y());
    } else {
        QRect r = rect();
        left = qAbs(x - r.left()) <= 5;
        right = qAbs(x - r.right()) <= 5;
        bottom = qAbs(y - r.bottom()) <= 5;
        bool hor = left | right;

        if (hor && bottom) {
            if (left)
                setCursor(Qt::SizeBDiagCursor);
            else
                setCursor(Qt::SizeFDiagCursor);
        } else if (hor) {
            setCursor(Qt::SizeHorCursor);
        } else if (bottom) {
            setCursor(Qt::SizeVerCursor);
        } else {
            setCursor(Qt::ArrowCursor);
        }
    }
}

void XMainWindow::mouseReleaseEvent(QMouseEvent *e)
{
    mouseDown = false;
}




相關推薦

QT定義視窗標題實現放大縮小

    去掉Qt視窗的標題邊框,重新定義標題欄,可以在標題欄上實現更多的功能,能滿足更多的開發需求,可以實現標題欄的拖動,雙擊,自定義放大縮小。      本文引用自:http://www.devbean.net/2011/10/custom-qt-titlebar/,感謝

Qt定義視窗標題

Qt技術學習班開始了,更多精彩、好玩的內容等著你,趕緊報名吧! 群號:655815739 一、簡述 今天晚上就如何用Qt自定義視窗標題欄,寫了一個小例子,比較基礎,實用。在此分享一下。 首先Qt是跨平臺的,所以在不同的平臺上視窗的外觀是不一樣的。比如在

QT定義標題窗體

1,定義兩個成員變數     bool        m_pressed;     QPoint        m_movePos; 2,重寫mousePressed,mouseMove,mouseRelease void mousePressEvent(QMouseE

QT定義視窗(無邊框,自由)

做專案中為了美觀,很少使用QT自帶的標題欄,取消邊框,自己實現邊框。自定義視窗,主要通過滑鼠事件實現。重寫QT視窗事件,具體參考程式碼註釋。 #ifndef CUSTOMWINDOW_H #defi

定義iTerm2標題和bash顯示當前git branch資訊

先來一張效果圖: 怎麼樣?是不是很酷? 下面我來介紹怎麼做到的。 首先 <span style="font-size:24px;">mkdir ~/.bash cd ~/.bash git clone https://github.com/jimeh/gi

QT定義視窗

qt 中允許自定義視窗控制元件,使之滿足特殊要求, (1)可以修改其顯示,自行繪製 (2)可以動態顯示 (3)可以新增事件,支援滑鼠和鍵盤操作 自定義控制元件可以直接在QtDesigner裡使用,可以直接加到父窗口裡。 繪製視窗 1.新建一個類,繼承與QWidget或QFrame,最好是繼承於QF

qt 定義視窗顯示滑鼠劃過的軌跡

滑鼠事件分為四種: 1.按下 2.擡起 3.移動 4.雙擊 滑鼠事件繼承與QWidget void mouseDoubleClickEvent(QMouseEvent *event) void mouseMoveEvent(QMouseEvent *event) void mousePres

微信小程式定義navigationBar標題

小程式預設使用的navigationBar只能設定顏色、文字,左側返回按鈕也是不可改變的,若要實現下方效果有解決方案,但是也有一定的問題。 1、更改app.json "window": { "navigationStyle": "custom" }, 2、自定義標題欄  使用custo

[Android] 定義頂部標題

思路及實現步驟 1.定義標題欄佈局 2.自定義TitleActivity控制標題欄按鈕監聽 3.在TitleActivity中實現標題欄以下內容切換 效果如下: 首先定義標題欄 layout_title.xml <?xml v

QTQT從零入門教程(十一):QT定義視窗

  首先是借鑑了網上的部落格,實現無邊框,自由拖動的自定義視窗效果。 #ifndef CUSTOMWINDOW_H #define CUSTOMWINDOW_H #include <QtGui> #include <QtWidg

Android 靈活的定義頂部標題

實現功能: 1)自定義View標題欄佈局; 2)靈活的可以自己傳入型別,選擇所需要的控制元件來顯示隱藏 3)相對於我之前寫過的一篇,免繼承,可直接在佈局裡使用 4)直接可以在佈局控制元件裡設定屬性 老規矩,上幾張效果圖: 由效果圖可見,這個

定義頂部標題和其事件監聽設定

iOS系統上方的工具欄很漂亮,也很實用,下面讓我們來仿製一下吧。 首先新建一個佈局檔案title.xml: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http:/

Qt定義視窗邊界可以拉伸

qt去掉外邊框以後 邊界不能拉伸。 第一。根據mouseevent事件到達邊界的時候自己處理 通過resize(來設定) 這種需要寫的程式碼較多 windows平臺上有更簡版的方法。 處理winevent裡面的 WM_NCHITTEST switch(message-&

Android 定義View 之 可隨意的View

因為趕專案本人停更兩個月 從今天開始又可以更新了 今天說一下這個可隨意拖動的view 簡單說一下這個view效果 和 發展 一開始這種效果是使用在網頁端的特別是購物類 例如某寶 某東 購物車和客服視窗 都有使用這個懸浮可拖動的設計效果 後來才發展到的移動端 還有

Android定義View-----TitleHead隨列表漸變---TitleHeadRecyclerView

    仿照網易的有道詞典的專欄詳情的上拉下來效果。特點繼承RecyclerView,重寫onTouchEvent()事件,根據不同情況執行不同的操作。使用LayoutParams改變View引數,實現View的大小改變。使用setX()方法,改變View的座標,實現View

flutter實現可縮放可放大的圖片功能

flutter實現可縮放可拖拽雙擊放大的圖片功能 可縮放可拖拽的功能,可實現圖片或者其他widget的縮放已經拖拽並支援雙擊放大的功能 我們知道官方提供了雙擊縮放,但是不支援拖拽的功能,我們要實現向百度地圖那樣可以縮放又可以拖拽的功能,官方的方法就不支援了。下面先演示下功能: 引數只有兩個:1、child

Qt重新實現QMouseEvent實現定義視窗

(1)pro檔案中加入 QT += gui (2)h檔案的類中加入標頭檔案: #include <QMouseEvent> 類中加入函式和變數宣告: protected: void mouseMoveEvent(QMouseEvent* event);

Qt定義標題詳細介紹(可放大縮小、關閉、標題具有漸變色)

前言 使用Qt自帶的標題欄可能沒有辦法適合我們的需求,例如標題欄的顏色,標題欄的寬度、高度,標題欄的放大、縮小、還原、關閉按鈕等都沒有辦法發生改變。因為預設的標題欄是和作業系統相關的、它會根據作業系統的變化而發生變化,在Window上不同風格的主題,在Qt程式

QT 定義標題

1、去除舊的標題欄 //去除QDialog對話方塊有上角問號 Qt::WindowFlags flags=Qt::Dialog;flags |=Qt::WindowCloseButtonHint;flags |=Qt::FramelessWindowHint; set

qt定義標題

寫一個qt介面程式,但是系統的標題欄太醜了,一看就像個demo,為了做的高階一點,必須去掉這個標題欄; 需要注意的幾個地方,首先要將系統的標題欄隱藏掉,然後新增自己的關閉最大化最小化按鈕,最後還要設定視窗的拖拽事件(因為去掉系統標題欄後不能拖拽) 1.隱藏系統標題欄