(QT-UI)四、自定义绘制一个悬浮窗

和上一个悬浮窗应用方式的区别是,this->setWindowFlag(Qt::Popup)效果默认是点击其他地方,就会失去焦点,从而隐藏窗口,

而本文中的窗口实现方式,可以添加更加灵活的事件,让悬浮窗展示更长时间,也可以自定义边框和导航按钮,或者完全的没有边框效果,而Popup效果,存在windows的窗口立体边框效果,所以可以根据项目情况,灵活选择运用

1、在已有的窗口上绘制一个悬浮条,先调整悬浮条的位置和大小,再将窗口设置为可见,完成悬浮展示效果。并且后续也可在wid中添加子控件

MyWidget::MyWidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::MyWidget)
{
    ui->setupUi(this);
    
    //初始化新的悬浮窗口,设置为可见, 并且将悬浮窗移动到左上角,大小设置为MyWidget的1/4
    ChildWidget* wid= new ChildWidget(this);//注意要传入this指针
    wid->move(0, 0);
    wid->resize(QSize(this->size().width() / 2, this->size().height() / 2));
    wid->setHidden(false);
}

这里要注意,创建子窗口时,需要传入this指针,才能继承MyWidget的属性,如样式表,WindowFlags等,否则只是相当于打开了一个完全独立的新widget。并且传入this指针后,后续子窗口的move,也将会按照父窗口的位置来计算,即wid->move(0,0)是移动到父窗口的左上角,而非整个屏幕的左上角。同理,如果已经将MyWidget设置为无边框的窗口,则wid则可以直接继承这种无边框的效果。

2、添加进入和离开事件,当进入控件时,才绘制悬浮条

//MyWidget.hpp
protected:
    void enterEvent(QEvent *);
    void leaveEvent(QEvent *);

//MyWidget.cpp
void MyWidget::enterEvent(QEvent *)
{
    m_wid->setHidden(false);
}
void MyWidget::leaveEvent(QEvent *)
{
    m_wid->setHidden(true);
}

在头文件中,重写enterEvent和leaveEvent,灵活调节悬浮条的显示情况

3、由于是一个新窗口,这是可以触发新窗口对应的鼠标点击事件,但是被遮住的部分则没有被点击到了,我们可以分别添加鼠标点击事件来确认.

//在MyWidget.cpp中实现mousePressEvent
void MyWidget::mousePressEvent(QMouseEvent *event)
{
    if(Qt::LeftButton == event->button())
    {
        qDebug() <<"点击区域是MyWidget";
    }
}
//在ChildWidget.cpp中实现mousePressEvent
void ChildWidget::mousePressEvent(QMouseEvent *event)
{
    if(Qt::LeftButton == event->button())
    {
        qDebug() <<"点击区域是ChildWidget";
    }
}

设置后,当点击非左上角区域时,可以通过日志查看到,响应的是MyWidget,点击区域是MyWidget。

当点击左上角区域时,可以通过日志查看到,响应的是ChildWidget,且只打印了“点击区域是ChildWidget”,并且没有打印MyWidget,所以由此判断被遮住的部分,则没有办法点击到了,所以在设计这种悬浮条或者悬浮窗的时候,需要预先去考虑窗口的大小,位置,并且避免出现多个叠加的情况

5、绘制子类悬浮窗时,可能出现的stylesheet没有生效的问题

子窗口调用setAttribute(Qt::WA_StyledBackground)即可。

 ChildWidget->setAttribute(Qt::WA_StyledBackground);
  • 6
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 这是一个使用 Qt 画图工具绘制自定义大小圆圈的例子: ``` #include <QApplication> #include <QWidget> #include <QPainter> int main(int argc, char *argv[]) { QApplication a(argc, argv); QWidget w; w.resize(400, 300); QPainter painter(&w); painter.setRenderHint(QPainter::Antialiasing); painter.setPen(Qt::red); painter.setBrush(Qt::red); int x = 100; // 圆圈的 x 坐标 int y = 100; // 圆圈的 y 坐标 int radius = 50; // 圆圈的半径 painter.drawEllipse(x - radius, y - radius, radius * 2, radius * 2); w.show(); return a.exec(); } ``` 请注意,在这个例子中,圆圈的坐标和半径都是固定的。如果你希望使用鼠标动态改变圆圈的位置和大小,可以使用鼠标事件处理器(mouse event handler)来实现。你可以在鼠标按下时记录当前鼠标的位置,在鼠标移动时动态更新圆圈的位置和大小,在鼠标释放时结束绘制。 ### 回答2: 以下是一个使用Qt编写的用鼠标绘制自定义大小圆圈的代码示例: ```cpp #include <QtWidgets> class DrawingWidget : public QWidget { public: DrawingWidget(QWidget *parent = nullptr) : QWidget(parent) { setFixedSize(400, 400); setMouseTracking(true); } protected: void paintEvent(QPaintEvent *event) override { QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing, true); foreach (QPointF point, m_points) { painter.drawEllipse(point, m_radius, m_radius); } } void mousePressEvent(QMouseEvent *event) override { if (event->button() == Qt::LeftButton) { m_points.append(event->pos()); update(); } } void mouseMoveEvent(QMouseEvent *event) override { if (event->buttons() & Qt::LeftButton) { m_points.append(event->pos()); update(); } } private: QList<QPointF> m_points; int m_radius = 10; }; int main(int argc, char *argv[]) { QApplication app(argc, argv); DrawingWidget widget; widget.show(); return app.exec(); } ``` 代码解析: 1. 创建一个名为`DrawingWidget`的自定义窗口部件,继承自`QWidget`。 2. 在构造函数中设置窗口大小为400x400,并开启鼠标追踪的功能。 3. 重写`paintEvent`函数,在其中使用`QPainter`绘制所有的圆圈。 4. 重写`mousePressEvent`函数,在鼠标左键按下时在当前鼠标位置绘制一个圆圈,并更新窗口。 5. 重写`mouseMoveEvent`函数,在鼠标左键按下并移动时,在当前鼠标位置添加一个圆圈,并更新窗口。 6. 在`main`函数中创建一个`QApplication`实例和一个`DrawingWidget`实例,并展示窗口。 当运行该代码后,会弹出一个窗口。在该窗口内,当你按住鼠标左键并移动时,会在鼠标位置绘制一个自定义大小的圆圈。 ### 回答3: 以下是一个使用Qt框架编写的代码段,该代码允许使用鼠标绘制自定义大小的圆圈: ```cpp #include <QtWidgets> #include <QWidget> class MyWidget : public QWidget { public: MyWidget(QWidget *parent = nullptr) : QWidget(parent) {} protected: void paintEvent(QPaintEvent *) override { QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing, true); painter.setPen(QPen(Qt::black, 2)); for (const QRectF &rect : m_circles) { painter.drawEllipse(rect); } } void mousePressEvent(QMouseEvent *event) override { m_lastPos = event->pos(); } void mouseMoveEvent(QMouseEvent *event) override { int width = abs(event->x() - m_lastPos.x()); int height = abs(event->y() - m_lastPos.y()); int x = qMin(event->x(), m_lastPos.x()); int y = qMin(event->y(), m_lastPos.y()); QRectF rect(x, y, width, height); m_circles.append(rect); update(); m_lastPos = event->pos(); } private: QList<QRectF> m_circles; QPoint m_lastPos; }; int main(int argc, char *argv[]) { QApplication app(argc, argv); MyWidget widget; widget.show(); return app.exec(); } ``` 这段代码创建了一个自定义的QWidget子类`MyWidget`,当鼠标在窗口上拖动时,会根据鼠标的位置绘制一个矩形,然后在绘制的矩形上绘制一个圆形。 在`paintEvent`函数中,我们使用`QPainter`类来绘制圆圈。`QPainter`类可以设置渲染提示和画笔样式,然后使用`drawEllipse`函数来绘制圆圈。`m_circles`列表保存绘制的所有圆圈的矩形区域。 在`mousePressEvent`和`mouseMoveEvent`函数中,我们记录鼠标的位置,并计算出绘制圆圈所需的矩形的位置和大小。然后将该矩形添加到`m_circles`列表中,并调用`update`函数来刷新窗口,触发`paintEvent`函数的调用来重新绘制圆圈。 最后,在`main`函数中,我们创建了一个`MyWidget`对象并显示出来,然后启动应用程序的事件循环。 要使用该代码,请将其保存为.cpp文件,然后使用Qt编译器编译并运行。运行后,您可以在窗口上使用鼠标绘制自定义大小的圆圈。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值