zoukankan      html  css  js  c++  java
  • Qt窗口定制

    qt中的QWidget窗口支持窗体绘制,但是不支持窗口标题栏绘制,想要美观的界面,还需要自己去定制,下面我就介绍一种定制窗体的方法

        一个窗口无非就3部分,标题栏、窗体和状态栏,接下来我定制的窗口没有状态栏,如果自己想加状态栏的话,照着这个模式自己也可以添加,说白了,窗口定制就是把完整的窗口分3部分定制,而每个部分又都是一个qt窗口

        定制窗口效果图如下,根据个人喜好,自己也可以定制不同的效果

    图1 定制窗口

        如图1所示,这个窗口包含两部分,标题栏和窗体,这两部分其实分别是一个没有标题栏的QWidget,接下来我分别介绍下这两部分

       标题栏

       构造函数代码如下​

     1 setAutoFillBackground(true);//自动填充背景色,防止继承父窗口背景色
     2 
     3 setStyleSheet(QStringLiteral("background:blue;"));//背景色
     4 
     5 ​setFixedHeight(30);//设置高度 看个人喜好 可以做微调​
     6 
     7 _p->minimize = new QToolButton(this);
     8 
     9 _p->maximize = new QToolButton(this);
    10 
    11 _p->close = new QToolButton(this);
    View Code

    /// 设置系统按钮图标.

      1 QPixmap pix = style()->standardPixmap(QStyle::SP_TitleBarCloseButton);
      2 
      3 _p->close->setIcon(pix);
      4 
      5 _p->maxPix = style()->standardPixmap(QStyle::SP_TitleBarMaxButton);
      6 
      7 _p->maximize->setIcon(_p->maxPix);
      8 
      9 pix = style()->standardPixmap(QStyle::SP_TitleBarMinButton);
     10 
     11 _p->minimize->setIcon(pix);
     12 
     13 _p->restorePix = style()->standardPixmap(QStyle::SP_TitleBarNormalButton);
     14 
     15 _p->minimize->setMinimumHeight(20);
     16 
     17 _p->close->setMinimumHeight(20);
     18 
     19 _p->maximize->setMinimumHeight(20);
     20 
     21 _p->label = new QLabel(this);
     22 
     23 _p->label->setAttribute(Qt::WA_TransparentForMouseEvents, true); //鼠标穿透
     24 
     25 _p->label->setStyleSheet(QStringLiteral("  font-size:12px;
     26 
     27     font - weight:Bold"));
     28 
     29     _p->label->setMargin(0);
     30 
     31 SetWindowTitle("title");
     32 
     33 QHBoxLayout *hbox = new QHBoxLayout;
     34 
     35 hbox->addWidget(_p->label);
     36 
     37 hbox->addWidget(_p->minimize);
     38 
     39 hbox->addWidget(_p->maximize);
     40 
     41 hbox->addWidget(_p->close);
     42 
     43 //_p->maximize->setVisible(false);
     44 
     45 hbox->insertStretch(1, 500);
     46 
     47 hbox->setSpacing(0);
     48 
     49 connect(_p->minimize, &QToolButton::clicked, this, [this]{
     50 
     51     BaseWidget * widget = qobject_cast(parent());
     52 
     53     if (widget)
     54 
     55     {
     56 
     57         widget->SetWindowMovePos(widget->pos());
     58 
     59         emit WindowDockedSignal();
     60 
     61     }
     62 
     63 });
     64 
     65 connect(_p->maximize, &QToolButton::clicked, this, &TitleBar::showMaxRestore);
     66 
     67 connect(_p->close, &QToolButton::clicked, this, [this]{emit WindowCloseSignal(_p->label->text()); });
     68 
     69 hbox->setMargin(1);
     70 
     71 hbox->setSpacing(2);
     72 
     73 setLayout(hbox);
     74 
     75void TitleBar::showMaxRestore()//最大化或者还原
     76 
     77 {
     78 
     79     if (_p->maxNormal)
     80 
     81     {
     82 
     83         _p->maxNormal = !_p->maxNormal;
     84 
     85         _p->maximize->setIcon(_p->maxPix);
     86 
     87     }
     88 
     89     else
     90 
     91     {
     92 
     93         _p->maxNormal = !_p->maxNormal;
     94 
     95         _p->maximize->setIcon(_p->restorePix);
     96 
     97     }
     98 
     99     emit WindowMaxRestoreSignal(_p->maxNormal);
    100 
    101 }
    102 
    103 void TitleBar::SetWindowTitle(const QString & title)//设置窗口标题
    104 
    105 {
    106 
    107     if (_p)
    108 
    109     {
    110 
    111         _p->label->setText(title);
    112 
    113     }
    114 
    115 }
    116 
    117 void TitleBar::SetWindowMaxable(bool isMax)
    118 
    119 {
    120 
    121     if (_p)
    122 
    123     {
    124 
    125         _p->maxNormal = isMax;
    126 
    127         if (_p->maxNormal)
    128 
    129         {
    130 
    131             _p->maximize->setIcon(_p->maxPix);
    132 
    133         }
    134 
    135         else
    136 
    137         {
    138 
    139             _p->maximize->setIcon(_p->restorePix);
    140 
    141         }
    142 
    143     }
    144 
    145 }
    146 
    147 void TitleBar::mousePressEvent(QMouseEvent * event)//移动窗口
    148 
    149 {
    150 
    151     QPoint mousePos = _p->minimize->mapFromParent(event->pos());
    152 
    153     if (_p->minimize->rect().contains(mousePos))//如果点击了最小化 则不能移动
    154 
    155     {
    156 
    157         return;
    158 
    159     }
    160 
    161     if (_p->maximize->rect().contains(mousePos))//如果点击了最大化不能移动
    162 
    163     {
    164 
    165         return;
    166 
    167     }
    168 
    169     _p->leftButtonPressed = true;
    170 
    171     _p->startPos = event->globalPos();
    172 
    173     _p->clickPos = mapToParent(event->pos());
    174 
    175 }
    176 
    177 void TitleBar::mouseReleaseEvent(QMouseEvent * event)
    178 
    179 {
    180 
    181     _p->leftButtonPressed = false;
    182 
    183 }
    184 
    185 void TitleBar::mouseMoveEvent(QMouseEvent * event)
    186 
    187 {
    188 
    189     if (_p->maxNormal)
    190 
    191     {
    192 
    193         return;
    194 
    195     }
    196 
    197     if (_p->leftButtonPressed)
    198 
    199     {
    200 
    201         parentWidget()->move(event->globalPos() - _p->clickPos);//移动父窗口
    202 
    203     }
    204 
    205 }
    206 
    207 void TitleBar::mouseDoubleClickEvent(QMouseEvent * event)
    208 
    209 {
    210 
    211     showMaxRestore();
    212 
    213 }
    View Code

        窗体定制

        直接上代码

    ​   cpp如下​

      1 setFrameShape(Panel);
      2 
      3 setMouseTracking(true);
      4 
      5 setWindowFlags(Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint | Qt::Tool);/// 隐藏窗口标题栏.
      6 
      7 setFixedSize(150, 190);
      8 
      9 _p->m_mouse_down = false;
     10 
     11 _p->m_titleBar = new TitleBar(this);
     12 
     13 _p->m_titleBar->installEventFilter(this);
     14 
     15 connect(_p->m_titleBar, &TitleBar::WindowDockedSignal
     16 
     17 , this, [this]{
     18 
     19 setFixedSize(_p->m_content->size());
     20 
     21 setMinimumSize(0, 0);
     22 
     23 setMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
     24 
     25 _p->m_titleBar->setVisible(false);
     26 
     27 });
     28 
     29 connect(_p->m_titleBar, &TitleBar::WindowMaxRestoreSignal
     30 
     31 , this, [this](bool isMax){
     32 
     33 if (isMax)
     34 
     35 {
     36 
     37 showMaximized();
     38 
     39 }
     40 
     41 else
     42 
     43 {
     44 
     45 showNormal();
     46 
     47 }
     48 
     49 });
     50 
     51 _p->m_content = new QWidget(this);
     52 
     53 QPalette plt = _p->m_content->palette();
     54 
     55 plt.setColor(QPalette::Window, QColor("#000000"));
     56 
     57 _p->m_content->setPalette(plt);//设置背景色黑色
     58 
     59 _p->m_content->setAutoFillBackground(true);
     60 
     61 _p->m_content->setAttribute(Qt::WA_PaintOnScreen, true);
     62 
     63 QVBoxLayout *vbox = new QVBoxLayout(this);
     64 
     65 vbox->addWidget(_p->m_titleBar);
     66 
     67 vbox->setStretchFactor(_p->m_titleBar, 0);
     68 
     69 vbox->setMargin(0);
     70 
     71 vbox->setSpacing(0);
     72 
     73 QVBoxLayout *layout = new QVBoxLayout(this);
     74 
     75 layout->addWidget(_p->m_content);
     76 
     77 layout->setMargin(0);
     78 
     79 layout->setSpacing(0);
     80 
     81 vbox->addLayout(layout);
     82 
     83 vbox->setStretchFactor(layout, 1);
     84 
     85 TitleBar * BaseWidget::GetTitleBar() const
     86 
     87 {
     88 
     89          if (_p)
     90 
     91          {
     92 
     93               return _p->m_titleBar;
     94 
     95           }
     96 
     97 }
     98 
     99 QWidget * BaseWidget::GetContentWidget() const
    100 
    101 {
    102 
    103      if (_p)
    104 
    105       {
    106 
    107             return _p->m_content;
    108 
    109        }
    110 
    111 }
    112 
    113 BaseWidget::State BaseWidget::GetWindowState() const
    114 
    115 {
    116 
    117     if (_p)
    118 
    119     {
    120 
    121           return _p->state;
    122 
    123      } 
    124 
    125 }
    126 
    127 void BaseWidget::SetWindowState(BaseWidget::State state)
    128 
    129 {
    130 
    131      if (_p)
    132 
    133       {
    134 
    135              _p->state = state;
    136 
    137              if (_p->state == _floating)
    138 
    139              {
    140 
    141                   _p->m_titleBar->setVisible(true);
    142 
    143                }
    144 
    145                else
    146 
    147               {
    148 
    149                      _p->m_titleBar->setVisible(false);
    150 
    151                }
    152 
    153        }
    154 
    155 }
    156 
    157 QPoint BaseWidget::GetWindowFloatPos() const
    158 
    159 {
    160 
    161     if (_p)
    162 
    163     {
    164 
    165           return _p->floatPostion;
    166 
    167     }  
    168 
    169 }
    170 
    171 void BaseWidget::SetWindowFloatPos(const QPoint & point)
    172 
    173 {
    174 
    175      if (_p)
    176 
    177      {
    178 
    179            _p->floatPostion = point;
    180 
    181      }
    182 
    183 }
    184 
    185 QPoint BaseWidget::GetWindowMovePos() const
    186 
    187 {
    188 
    189     if (_p)
    190 
    191     {
    192 
    193     return _p->m_restorePos;
    194 
    195     }
    196 
    197 }
    198 
    199 void BaseWidget::SetWindowMovePos(const QPoint & pos)
    200 
    201 {
    202 
    203     if (_p)
    204 
    205     {
    206 
    207           _p->m_restorePos = pos;
    208 
    209      }
    210 
    211 }
    212 
    213 bool BaseWidget::eventFilter(QObject * object, QEvent * event)
    214 
    215 {
    216 
    217 if (object == _p->m_titleBar)
    218 
    219 {
    220 
    221      if (event->type() == QEvent::MouseMove)
    222 
    223      {
    224 
    225         QMouseEvent * mouseEvent = static_cast(event);
    226 
    227         if (mouseEvent && mouseEvent->button() & Qt::LeftButton)
    228 
    229          {
    230 
    231                 return true;//不做处理
    232 
    233             }
    234 
    235         }
    236 
    237     }
    238 
    239      return QWidget::eventFilter(object, event);
    240 
    241 }
    242 
    243 void BaseWidget::mousePressEvent(QMouseEvent * event)
    244 
    245 {
    246 
    247      if (event->button() == Qt::LeftButton)
    248 
    249      {
    250 
    251         _p->m_mouse_down = true;
    252 
    253          _p->dragPostion = event->globalPos() - frameGeometry().topLeft();
    254 
    255          event->accept();
    256 
    257      }
    258 
    259 }
    260 
    261 void BaseWidget::mouseMoveEvent(QMouseEvent * event)
    262 
    263 {
    264 
    265     if (_p->state != _floating || isMaximized())//如果窗口不是悬浮状态 或者最大化 不允许拖动
    266 
    267     {
    268 
    269          return;
    270 
    271     }
    272 
    273     if (_p->m_mouse_down)
    274 
    275     {
    276 
    277         move(event->globalPos() - _p->dragPostion);
    278 
    279         event->accept();
    280 
    281     }
    282 
    283 }
    284 
    285 void BaseWidget::mouseReleaseEvent(QMouseEvent * event)
    286 
    287 {
    288 
    289     _p->m_mouse_down = false; 
    290 
    291 }
    292 
    293 void BaseWidget::mouseDoubleClickEvent(QMouseEvent * event)
    294 
    295 {
    296 
    297  if (_p->state == _dock)
    298 
    299  {
    300 
    301          _p->state = _floating;
    302 
    303          _p->m_titleBar->setVisible(true);
    304 
    305          setParent(nullptr);
    306 
    307          setWindowFlags(Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint |      Qt::Tool);
    308 
    309          move(GetWindowMovePos());
    310 
    311         show();
    312 
    313     }
    314 
    315 }
    View Code

    ​    有如上两部分代码,功能基本可以实现

  • 相关阅读:
    「疫期集训day7」周期
    「字符串」哈希板子
    「疫期集训day6」雨林
    「疫期集训day5」火焰
    「数据结构」对顶堆
    「STL中的常用函数 容器」
    「单调队列优化DP」P2034 选择数字
    bootstrap table使用及遇到的问题
    ArcGIS栅格影像怎么从WGS84地理坐标转成Xian80投影坐标
    arcgis如何求两个栅格数据集的差集
  • 原文地址:https://www.cnblogs.com/swarmbees/p/5621526.html
Copyright © 2011-2022 走看看