• QT自定义窗口(模拟MainWindow)


    在这里自定义窗口是通过继承于QFrame,内部分为上下两部分,上半部分就是标题栏,下面是窗口的具体内容。上下两部分通过布局固定位置。最后窗口的各种鼠标拖动,缩放,等操作通过添加鼠标事件来完成一个窗口的常规功能。当然,这个标题栏可以通过布局的改变把它放到任意地方。

    下面是实现的代码: 
    #pragma once 
    #ifndef CUSTOMWIDGET_H_ 
    #define CUSTOMWIDGET_H_

    #include <QtWidgets/QFrame>

    class QToolButton; 
    class CustomWidget : public QFrame 
    {

    Q_OBJECT
    

    public:

    explicit CustomWidget();
    ~CustomWidget();
    void setContentWidget(QWidget *contentWidget);
    void setTitleInfo(const QString &titleString, const QPixmap &windowIcon);
    

    public slots:

    void slotShowSmall();
    void slotShowMaxRestore();
    void onMoveWindow();
    

    signals:

    void moveWindow();
    

    protected:

    void mousePressEvent(QMouseEvent *);
    void mouseMoveEvent(QMouseEvent *);
    void mouseReleaseEvent(QMouseEvent *);
    bool nativeEvent(const QByteArray & eventType, void * message, long * result);
    void paintEvent(QPaintEvent *);
    

    private:

    bool isMax;
    bool isPress;
    QPoint startPos;
    QPoint clickPos;
    QWidget *m_pTitleWidget;//顶栏窗体
    QWidget *m_pContentWidget;//内容窗体
    QPixmap maxPixmap;
    QPixmap restorePixmap;
    QToolButton *m_pMaxButton;
    

    };

    #endif //!CUSTOMWIDGET_H_

    customWidget.cpp:

    #include "stdafx.h" 
    #include "customwidget.h" 
    #include <QtWidgets/QLabel> 
    #include <QtWidgets/QToolButton> 
    #include <QtWidgets/QHBoxLayout> 
    #include <QtCore/QEvent> 
    #include <Window.h>

    static const int TITLE_HEIGHT = 40;//标题栏高度 
    static const int FRAME_BORDER = 2;//边框宽度 
    CustomWidget::CustomWidget() 
    : m_pContentWidget(0) 
    //, m_llLocalWinId(0) 
    //, m_llRemoteWinId(0)
     
    {

    this->setWindowFlags(Qt::FramelessWindowHint);
    this->setAttribute(Qt::WA_TranslucentBackground);
    this->setMouseTracking(true);
    
    isMax = false;
    isPress = false;
    m_pTitleWidget = new QWidget();
    

    }

    CustomWidget::~CustomWidget() 

    }

    void CustomWidget::setContentWidget(QWidget *contentWidget) 
    {

    if (contentWidget)
    {
        m_pContentWidget = contentWidget;
        m_pContentWidget->move(m_pTitleWidget->rect().bottomLeft());
        m_pContentWidget->show();
        resize(m_pTitleWidget->width(), m_pTitleWidget->height() + m_pContentWidget->height());
    }
    

    }

    void CustomWidget::setTitleInfo(const QString &titleString, const QPixmap &windowIcon) 
    {

    QLabel *logoLabel = new QLabel();
    logoLabel->setPixmap(windowIcon);
    logoLabel->setFixedSize(16, 16);
    logoLabel->setScaledContents(true);
    
    QLabel *titleLabel = new QLabel();
    titleLabel->setText(titleString);
    QFont titleFont = titleLabel->font();
    titleFont.setBold(true);
    titleLabel->setFont(titleFont);
    titleLabel->setObjectName("whiteLabel");
    titleLabel->setStyleSheet("color:white;");
    
    QToolButton *minButton = new QToolButton();
    connect(minButton, SIGNAL(clicked()), this, SLOT(slotShowSmall()));
    m_pMaxButton = new QToolButton();
    connect(m_pMaxButton, SIGNAL(clicked()), this, SLOT(slotShowMaxRestore()));
    QToolButton *closeButton = new QToolButton();
    connect(closeButton, SIGNAL(clicked()), this, SLOT(close()));
    connect(this, SIGNAL(moveWindow()), this, SLOT(onMoveWindow()));
    
    QHBoxLayout *titleLayout = new QHBoxLayout();
    titleLayout->addWidget(logoLabel);
    titleLayout->addWidget(titleLabel);
    titleLabel->setContentsMargins(5, 0, 0, 0);
    titleLayout->addStretch();
    titleLayout->addWidget(minButton, 0, Qt::AlignTop);
    titleLayout->addWidget(m_pMaxButton, 0, Qt::AlignTop);
    titleLayout->addWidget(closeButton, 0, Qt::AlignTop);
    titleLayout->setSpacing(0);
    titleLayout->setContentsMargins(5, 0, 0, 0);
    
    m_pTitleWidget->setFixedSize(600, TITLE_HEIGHT);
    m_pTitleWidget->setLayout(titleLayout);
    m_pTitleWidget->installEventFilter(0);
    m_pTitleWidget->setAutoFillBackground(true);
    QPalette palette;
    palette.setColor(QPalette::Background, QColor(31,25,25));
    m_pTitleWidget->setPalette(palette);
    

    }

    void CustomWidget::slotShowSmall()//最小化 

    this->showMinimized(); 
    }

    void CustomWidget::slotShowMaxRestore()//还原按钮 
    {

    if (isMax) {
        this->showNormal();
        m_pMaxButton->setIcon(maxPixmap);
    }
    else {
        this->showMaximized();
        m_pMaxButton->setIcon(restorePixmap);
    }
    isMax = !isMax;
    

    }

    void CustomWidget::onMoveWindow() 

    //m_pContentWidget->move(m_pTitleWidget->rect().bottomLeft()); 
    }

    void CustomWidget::mousePressEvent(QMouseEvent *e) 
    {

    startPos = e->globalPos();
    clickPos = e->pos();
    
    if (e->button() == Qt::LeftButton) {
        if (e->type() == QEvent::MouseButtonPress) {
            isPress = true;
        }
        else if (e->type() == QEvent::MouseButtonDblClick && e->pos().y() <= TITLE_HEIGHT) {
            this->slotShowMaxRestore();
        }
    }
    

    }

    void CustomWidget::mouseMoveEvent(QMouseEvent *e) 
    {

    if (isMax || !isPress) {
        return;
    }
    this->move(e->globalPos() - clickPos);
    emit moveWindow();
    

    }

    void CustomWidget::mouseReleaseEvent(QMouseEvent *) 

    isPress = false; 
    }

    bool CustomWidget::nativeEvent(const QByteArray & eventType, void * message, long * result)//实现拖拽边框的效果 
    {

    Q_UNUSED(eventType);
    const int HIT_BORDER = 5;
    const MSG *msg = static_cast<MSG*>(message);
    if (msg->message == WM_NCHITTEST) {
        int xPos = ((int)(short)LOWORD(msg->lParam)) - this->frameGeometry().x();
        int yPos = ((int)(short)HIWORD(msg->lParam)) - this->frameGeometry().y();
        if (this->childAt(xPos, yPos) == 0) {
            *result = HTCAPTION;
        }
        else {
            return false;
        }
        if (xPos > 0 && xPos < HIT_BORDER) {
            *result = HTLEFT;
        }
        if (xPos >(this->width() - HIT_BORDER) && xPos < (this->width() - 0)) {
            *result = HTRIGHT;
        }
        if (yPos > 0 && yPos < HIT_BORDER) {
            *result = HTTOP;
        }
        if (yPos >(this->height() - HIT_BORDER) && yPos < (this->height() - 0)) {
            *result = HTBOTTOM;
        }
        if (xPos > 0 && xPos < HIT_BORDER && yPos > 0 && yPos < HIT_BORDER) {
            *result = HTTOPLEFT;
        }
        if (xPos >(this->width() - HIT_BORDER) && xPos < (this->width() - 0) && yPos > 0 && yPos < HIT_BORDER) {
            *result = HTTOPRIGHT;
        }
        if (xPos > 0 && xPos < HIT_BORDER && yPos >(this->height() - HIT_BORDER) && yPos < (this->height() - 0)) {
            *result = HTBOTTOMLEFT;
        }
        if (xPos >(this->width() - HIT_BORDER) && xPos < (this->width() - 0) && yPos >(this->height() - HIT_BORDER) && yPos < (this->height() - 0)) {
            *result = HTBOTTOMRIGHT;
        }
        return true;
    }
    return false;
    

    }

    void CustomWidget::paintEvent(QPaintEvent *e) 
    {//绘制边框

    int border = FRAME_BORDER;
    if (this->isMaximized()) {
        border = 0;
    }
    
    QPainter painter(this);
    QPainterPath painterPath;
    painterPath.setFillRule(Qt::WindingFill);
    painterPath.addRect(border, border, this->width() - 2 * border, this->height() - 2 * border);
    painter.setRenderHint(QPainter::Antialiasing, true);
    painter.fillPath(painterPath, QBrush(Qt::black));
    QColor color(200, 200, 200);
    for (int i = 0; i<border; i++) {
        color.setAlpha((i + 1) * 30);
        painter.setPen(color);
        painter.drawRect(border - i, border - i, this->width() - (border - i) * 2, this->height() - (border - i) * 2);
    }
    
    painter.setPen(Qt::NoPen);
    painter.setBrush(Qt::black);
    // 这里可以在资源中指定一张标题背景图片  
    //painter.drawPixmap(QRect(border, border, this->width()-2*border, this->height()-2*border), QPixmap(DEFAULT_SKIN));  
    painter.drawRect(QRect(border, TITLE_HEIGHT, this->width() - 2 * border, this->height() - TITLE_HEIGHT - border));
    QFrame::paintEvent(e);
    


    ///////////////全文完

    http://blog.csdn.net/u011915578/article/details/46924151

  • 相关阅读:
    bzoj1098 1301
    bzoj3237
    bzoj3170
    bzoj4008
    一些题解
    bzoj4028
    bzoj3196
    redis学习
    quartz学习
    电商618 压测、优化、降级预案
  • 原文地址:https://www.cnblogs.com/findumars/p/4963589.html
Copyright © 2020-2023  润新知