设为首页 加入收藏

TOP

【Qt6】嵌套 QWindow(一)
2023-07-23 13:31:53 】 浏览:65
Tags:Qt6 嵌套 QWindow

在上个世纪的文章中,老周简单介绍了 QWindow 类的基本使用——包括从 QWindow 类派生和从 QRasterWindow 类派生。

其实,QWindow 类并不是只能充当主窗口用,它也可以嵌套到父级窗口中,变成子级对象。咱们一般称之为【控件】。F 话不多讲,下面咱们用实际案例来说明。

这个例子中老周定义了两个类:

MyControl:子窗口对象,充当控件角色。这里实现一个类似开关的控件。【关闭】状态下,控件的背景呈现为灰色,金色方块位于最左侧;当控件处于【开启】状态下,控件背景为红色,金色方块位于最右侧。
MyWindow:作为窗口使用,里面包含 MyControl 对象。
先看 MyControl 类。
class MyControl : public QRasterWindow
{
    Q_OBJECT

public:
    MyControl(QWindow *parent = nullptr);

private:
    // “开启”状态时的背景色
    QColor _on_bgcolor;
    // “关闭”状态时的背景色
    QColor _off_bgcolor;
    // 当前状态
    bool _state;

signals:
    // 信号
    void stateChanged(bool isOn); public:
    // 获取状态
    inline bool state() const { return _state; }
    // 修改状态
    inline void setState(bool s)
    {
        _state = s;
        // 发出信号
 emit stateChanged(_state);
    }

protected:
    // 重写方法
    void paintEvent(QPaintEvent *event) override;
    void mousePressEvent(QMouseEvent* evebt) override;
};

在私有成员中,两个 QColor 类型的变量分别表示控件处于【开】或【关】状态时的背景色。_state 是一个布尔值,true就是【开】,false就是【关】,用来存储控件的当前状态。

公共方法 state 获取当前状态,setState 方法用来修改当前状态,同时会发出 stateChanged 信号。信号成员咱们先放一下,后文再叙。

两个虚函数的重写。paintEvent 负责画出控件的模样;mousePressEvent 当鼠标左键按下时改变控件的状态。实现点击一下开启,再点击一下关闭的功能。

接下来是实现各个成员。先是构造函数。

MyControl::MyControl(QWindow* parent)
    :QRasterWindow::QRasterWindow(parent),
     _state(false),
     _on_bgcolor(QColor("red")),
     _off_bgcolor(QColor("gray"))
{

}

构造函数主要用来初始化几个私有成员。下面代码实现鼠标左键按下后更改状态。

void MyControl::mousePressEvent(QMouseEvent *event)
{
    if(! (event->buttons() & Qt::MouseButton::LeftButton))
        return;  // 如果按的不是左键就 PASS
    
    this->setState(!this->state());
    update();
}

每次点击后控件的状态都会取反(开变关,关变开),为了反映改变必须重新绘制控件,所以要调用 update 方法。

paintEvent 中实现绘制的过程。

void MyControl::paintEvent(QPaintEvent* event)
{
    // 如果当前为不可见状态,就不绘图了
    if(!isExposed())
        return;
    // 要绘制的区域
    QRect rect = event -> rect();

    QPainter painter;
    painter.begin(this);
    // 根据状态填充背景
    QBrush bgbrush;
    bgbrush.setStyle(Qt::SolidPattern);     if(_state)
    {
        bgbrush.setColor(_on_bgcolor);
    }
    else
    {
        bgbrush.setColor(_off_bgcolor);
    }
    painter.fillRect(rect, bgbrush);

    QRect rectSq;
    // 如果是“开”的状态,绿色矩形在右侧
    if(_state)
    {
        rectSq.setX(rect.width() / 3 * 2);
        rectSq.setWidth(rect.width() / 3);
    }
    // 如果为“关”的状态,绿色矩形在左侧
    else{
        rectSq.setWidth(rect.width() / 3);
    }
    rectSq.setHeight(rect.height());
    painter.fillRect(rectSq, QColor("gold"));
    painter.end();
}

绘制分两步走。第一步是填充背景矩形,如果【开】就填充红色,如果【关】就填充灰色。此处用到了 QBrush 对象。根据不同颜色调用 setColor 方法来设置。这里要注意 QBrush 对象要调用 setStyle 方法设置画刷样式为 SolidPattern。这是因为 QBrush 类默认的 style 是 NoBrush,因此要手动设置一下,不然看不到绘制。

第二步是绘制小方块。当控件状态为【开】时方块在右边,状态为【关】时方块在左边。小方块的宽度是控件宽度的 1/3,高度与控件相同。要显式调用 setHeight 方法设置矩形高度(因为它默认为0)。记得小方块的左上角的 X 坐标也要调整的。

 

下面是窗口 MyWindow 的成员。

class MyWindow : public QRasterWindow
{
    Q_OBJECT

public:
    MyWindow(QWindow *parent = nullptr);

private:
    MyControl *_control;
    void initUI();

protected:
    void paintEvent(QPaintEvent *event) override;
};

重写的 paintEvent 方法负责画窗口的背景。私有成员 initUI 用于初始化子窗口(MyControl对象)。initUI 方法在构造函数中调用。

MyWindow::MyWindow(QWindow *parent)
    :QRasterWindow::QRasterWindow(parent)
{
    initUI();
}

void MyWindow::initUI()
{
    // 初始化窗口
    setTitle("示例程序");
    resize(550, 450);
    setMinimumSize(QSize(340, 200));
    _control = new MyControl(this);
    // 初始化子窗口
    _control->setPosition(35, 40);
    _cont
首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇玩一玩 Ubuntu 下的 VSCode 编程 下一篇<三>从编译器角度理解C++代..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目