zoukankan      html  css  js  c++  java
  • Qt多文档实现屏幕空间(类似监控多画面)效果

    Qt多文档程序中的每一个子窗口就是一个个的画面,子窗口可以自由拖动,激活来使用。
    现实中,类似于监控的多画面同时排列显示比较常见,也比较实用。
    实现思路:
    1、响应窗口的resizeEvent事件
    2、根据分割数目,通过setGeometry动态设置子窗口相对位置
    代码如下:

      1 #ifndef MAINWINDOW_H
      2 #define MAINWINDOW_H
      3 
      4 #include <QMainWindow>
      5 
      6 class QMdiArea;
      7 class QMdiSubWindow;
      8 class MainWindow : public QMainWindow
      9 {
     10     Q_OBJECT
     11 
     12 public:
     13     MainWindow(QWidget *parent = nullptr);
     14     ~MainWindow();
     15 
     16 protected:
     17     virtual void resizeEvent(QResizeEvent *event);
     18 
     19 private:
     20     void splitWindow(QList<QMdiSubWindow *> list, QSize windowSize);
     21 
     22 private:
     23     QMdiArea    *m_area;
     24 };
     25 
     26 #endif // MAINWINDOW_H
     27 
     28 
     29 #include "MainWindow.h"
     30 #include <QMdiArea>
     31 #include <QMdiSubWindow>
     32 #include <QResizeEvent>
     33 #include "View.h"
     34 #include "Scene.h"
     35 
     36 MainWindow::MainWindow(QWidget *parent)
     37     : QMainWindow(parent)
     38     , m_area(new QMdiArea())
     39 {
     40     /// set mdi area
     41     setCentralWidget(m_area);
     42 
     43     /// test...
     44     for (int i = 0; i < 4; ++i) {
     45         View *view = new View(this);
     46         Scene *scene = new Scene();
     47         view->setScene(scene);
     48         QMdiSubWindow *subWindow = new QMdiSubWindow();
     49         subWindow->setWidget(view);
     50         subWindow->setWindowFlags(Qt::FramelessWindowHint);
     51         m_area->addSubWindow(subWindow);
     52     }
     53 }
     54 
     55 MainWindow::~MainWindow()
     56 {
     57 
     58 }
     59 
     60 void MainWindow::resizeEvent(QResizeEvent *event)
     61 {
     62     if (nullptr != m_area){
     63         QList<QMdiSubWindow *> list = m_area->subWindowList();
     64         QSize windowSize = event->size();
     65         splitWindow(list, windowSize);
     66     }
     67 
     68 }
     69 
     70 void MainWindow::splitWindow(QList<QMdiSubWindow *> list, QSize windowSize)
     71 {
     72     int subWindow = list.size();
     73     switch (subWindow) {
     74     case 1:
     75         list.at(0)->setGeometry(0, 0, windowSize.width(), windowSize.height());
     76         break;
     77     case 2:
     78         for (int i = 0; i < subWindow; ++i) {
     79             if (i == 0){
     80                 list.at(i)->setGeometry(0, 0, windowSize.width() / 2, windowSize.height());
     81             }
     82             else {
     83                 list.at(i)->setGeometry(windowSize.width() / 2, 0, windowSize.width() / 2, windowSize.height());
     84             }
     85         }
     86         break;
     87     case 3:
     88     case 4:
     89         for (int i = 0; i < subWindow; ++i) {
     90             switch (i){
     91             case 0:
     92                 list.at(i)->setGeometry(0, 0, windowSize.width() / 2, windowSize.height() / 2);
     93                 break;
     94             case 1:
     95                 list.at(i)->setGeometry(windowSize.width() / 2, 0, windowSize.width() / 2, windowSize.height() / 2);
     96                 break;
     97             case 2:
     98                 list.at(i)->setGeometry(0, windowSize.height() / 2,  windowSize.width() / 2, windowSize.height() / 2);
     99                 break;
    100             case 3:
    101                 list.at(i)->setGeometry( windowSize.width() / 2, windowSize.height() / 2, windowSize.width() / 2, windowSize.height() / 2);
    102                 break;
    103             }
    104         }
    105 
    106     }
    107 }
     1 #ifndef VIEW_H
     2 #define VIEW_H
     3 
     4 #include <QGraphicsView>
     5 
     6 class View : public QGraphicsView
     7 {
     8 public:
     9     View(QWidget *parent = nullptr);
    10 };
    11 
    12 #endif // VIEW_H
    13 
    14 #include "View.h"
    15 
    16 
    17 View::View(QWidget *parent)
    18     : QGraphicsView(parent)
    19 {
    20 
    21 }
    #ifndef SCENE_H
    #define SCENE_H
    
    #include <QGraphicsScene>
    
    class Scene : public QGraphicsScene
    {
    public:
        Scene();
    };
    
    #endif // SCENE_H
    
    #include "Scene.h"
    #include <QGraphicsRectItem>
    
    Scene::Scene()
    {
        QGraphicsRectItem *item = new QGraphicsRectItem();
        item->setPos(100, 100);
        item->setRect(0, 0, 200, 100);
        item->setFlags(QGraphicsItem::ItemIsMovable);
        addItem(item);
    }

    构建运行:

    扩展:如果想分割一个单独的QGraphicsScene,可以将窗口中心设置为(0,0),左上,右上,左下,右下分成四个区域。绘制每个图元时,在paint绘制函数中使用painter->setClipRect设置所在剪切区域即可,相关代码片段如下:

    // 图元类代码片段
    void QRectItem::paint(QPainter *painter,
                          const QStyleOptionGraphicsItem *option,
                          QWidget *widget)
    {
        QPainterPath path;
        path.addRect(m_clipRect);
        painter->setClipPath(path);
    }
    
    void QRectItem::setClipRect(QRect rect)
    {
        m_clipRect = rect;
    }
    
    
    // 场景类代码片段
    // split scene
    QPen pen(Qt::black, 1, Qt::DashLine);
    addLine(QLine(-10000, 0, 10000, 0), pen);
    addLine(QLine(0, -10000, 0, 10000), pen);
    
    QRectItem *item1 = new QRectItem();
    item1->setPos(-200, -200);
    item1->setRect(0, 0, 200, 100);
    item1->setClipRect(QRect(-1000, -1000, 1000, 1000));
    item1->setFlags(QGraphicsItem::ItemIsMovable);
    addItem(item1);
    View Code
  • 相关阅读:
    CCF NOI1006 捡石头
    POJ NOI MATH-7648 蓄水池水管问题
    CCF NOI1005 存款收益
    CCF NOI1004 填充矩形
    CCF NOI1003 猜数游戏
    CCF NOI1002 三角形
    Project Euler Problem 26 Reciprocal cycles
    HDU1799 循环多少次?
    CCF NOI1001 温度转换
    POJ NOI MATH-7647 余数相同问题
  • 原文地址:https://www.cnblogs.com/MakeView660/p/12503226.html
Copyright © 2011-2022 走看看