我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Qt实现对齐线功能的示例代码

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Qt实现对齐线功能的示例代码

现有功能

1.添加任意数量的按钮。

2.移动按钮,通过对齐线来设置按钮位置。

3.自动吸附。

运行结果

源码

button.h

#ifndef BUTTON_H
#define BUTTON_H

#include <QPushButton>
#include <QWidget>
#include <QMouseEvent>


class Button: public QPushButton
{
    Q_OBJECT

public:
    Button(QString text, QWidget *parent=nullptr);
    ~Button();

protected:
    void mousePressEvent(QMouseEvent *event);
    void mouseMoveEvent(QMouseEvent *event);
    void mouseReleaseEvent(QMouseEvent *event);

private:
    int startX;
    int startY;
};

#endif // BUTTON_H

button.cpp

#include "button.h"
#include "window.h"

Button::Button(QString text, QWidget *parent):QPushButton(text, parent)
{

}

Button::~Button() {

}

void Button::mousePressEvent(QMouseEvent *event) {
    QPushButton::mousePressEvent(event);
    this->startX = event->x();
    this->startY = event->y();
}

void Button::mouseMoveEvent(QMouseEvent *event) {
    QPushButton::mouseMoveEvent(event);
    int disX = event->x() - this->startX;
    int disY = event->y() - this->startY;
    this->move(this->x()+disX, this->y()+disY);

    Window *win = (Window*) this->parent();
    win->checkPos(this);
}

void Button::mouseReleaseEvent(QMouseEvent *event) {
    QPushButton::mouseReleaseEvent(event);
}

window.h

#ifndef WINDOW_H
#define WINDOW_H

#include <QWidget>
#include <QSpinBox>
#include <QPainter>
#include <QPaintEvent>
#include <QPushButton>
#include <QList>
#include <QPen>

#include "button.h"

class Window : public QWidget
{
    Q_OBJECT

public:
    Window(QWidget *parent = nullptr);
    ~Window();
    void checkPos(Button *movingBtn);                   // 检查按钮位置

protected:
    void paintEvent(QPaintEvent *event);

private slots:
    void changeBtnNum(int newNum);                      // 改变按钮数量

private:
    void drawVerticalCenterLine(QPainter &painter);     // 绘制垂直中心线
    void drawHorizontalCenterLine(QPainter &painter);   // 绘制水平中心线
    void drawBtnLeftLine(QPainter &painter);            // 绘制按钮左侧线
    void drawBtnTopLine(QPainter &painter);             // 绘制按钮顶部线
    void checkBtnTopLine(Button *movingBtn);            // 比对当前移动按钮和其他按钮顶部的位置
    void checkBtnLeftLine(Button *movingBtn);           // 比对当前移动按钮和其他按钮左侧的位置
    void checkWindowCenterLines(Button *movingBtn);     // 比对按钮和中心线的位置

private:
    QSpinBox *spinBox;
    QList<Button *> btnList;

    int lineShowThresholdValue;                         // 线条显示阈值
    int lineAdsorbThresholdValue;                       // 线条吸附阈值
    bool isVerticalCenterLineShown;                     // 是否显示中心竖线
    bool isHorizontalCenterLineShown;                   // 是否显示中心横线
    bool isBtnLeftLineShown;                            // 是否显示按钮左侧线条
    bool isBtnTopLineShown;                             // 是否显示按钮顶部线条

    int btnLeftLineX;                                   // 按钮左侧线x坐标
    int btnTopLineY;                                    // 按钮顶部线y坐标

    QPen pen1;                                          // 用来绘制中心对齐线
    QPen pen2;                                          // 用来绘制按钮间的对齐线
};
#endif // WINDOW_H

window.cpp

#include "window.h"
#include <Qt>
#include <QString>
#include <cstdlib>

Window::Window(QWidget *parent): QWidget(parent)
{
    this->resize(500, 500);
    this->spinBox = new QSpinBox(this);
    this->spinBox->setValue(0);
    this->spinBox->move(10, 10);
    connect(this->spinBox, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), this, &Window::changeBtnNum);

    this->lineShowThresholdValue = 5;
    this->lineAdsorbThresholdValue = 3;

    this->isVerticalCenterLineShown = false;
    this->isHorizontalCenterLineShown = false;
    this->isBtnLeftLineShown = false;
    this->isBtnTopLineShown = false;

    this->btnLeftLineX = 0;
    this->btnTopLineY = 0;

    this->pen1 = QPen(Qt::darkBlue);
    this->pen2 = QPen(Qt::gray);
}

Window::~Window()
{
}

void Window::paintEvent(QPaintEvent *event) {
    QWidget::paintEvent(event);

    QPainter painter(this);
    painter.setPen(this->pen1);

    if (this->isVerticalCenterLineShown) {
        this->drawVerticalCenterLine(painter);
    }

    if (this->isHorizontalCenterLineShown) {
        this->drawHorizontalCenterLine(painter);
    }

    painter.setPen(this->pen2);
    if (this->isBtnLeftLineShown) {
        this->drawBtnLeftLine(painter);
    }

    if (this->isBtnTopLineShown) {
        this->drawBtnTopLine(painter);
    }
}

void Window::drawVerticalCenterLine(QPainter &painter) {
    int verticalCenterValue = int(this->width() / 2);
    painter.drawLine(verticalCenterValue, 0, verticalCenterValue, this->height());
}

void Window::drawHorizontalCenterLine(QPainter &painter) {
    int horizontalCenterValue = int(this->height() / 2);
    painter.drawLine(0, horizontalCenterValue, this->width(), horizontalCenterValue);
}

void Window::drawBtnLeftLine(QPainter &painter) {
    int x = this->btnLeftLineX;
    painter.drawLine(x, 0, x, this->height());
}

void Window::drawBtnTopLine(QPainter &painter) {
    int y = this->btnTopLineY;
    painter.drawLine(0, y, this->width(), y);
}

void Window::checkPos(Button *movingBtn) {
    this->checkBtnTopLine(movingBtn);
    this->checkBtnLeftLine(movingBtn);
    this->checkWindowCenterLines(movingBtn);
    this->update();
}

void Window::checkBtnTopLine(Button *movingBtn) {
    int x = movingBtn->x();
    int y = movingBtn->y();

    for (int i=0; i<this->btnList.size(); i++) {
        Button *btn = this->btnList.at(i);
        if (btn == movingBtn) {
            continue;
        }

        if (y>btn->y()-this->lineShowThresholdValue && y<btn->y()+this->lineShowThresholdValue) {
            this->isBtnTopLineShown = true;
            this->btnTopLineY = btn->y();

            if (y>btn->y()-this->lineAdsorbThresholdValue && y<btn->y()+this->lineAdsorbThresholdValue) {
                movingBtn->move(x, btn->y());
            }
            return;
        }
        else {
            this->isBtnTopLineShown = false;
            this->btnTopLineY = 0;
        }
    }
}

void Window::checkBtnLeftLine(Button *movingBtn) {
    int x = movingBtn->x();
    int y = movingBtn->y();

    for (int i=0; i<this->btnList.size(); i++) {
        Button *btn = this->btnList.at(i);
        if (btn == movingBtn) {
            continue;
        }

        if (x>btn->x()-this->lineShowThresholdValue && x<btn->x()+this->lineShowThresholdValue) {
            this->isBtnLeftLineShown = true;
            this->btnLeftLineX = btn->x();

            if (x>btn->x()-this->lineAdsorbThresholdValue && x<btn->x()+this->lineAdsorbThresholdValue) {
                movingBtn->move(btn->x(), y);
            }
            return;
        }
        else {
            this->isBtnLeftLineShown = false;
            this->btnLeftLineX = 0;
        }
    }
}

void Window::checkWindowCenterLines(Button *movingBtn) {
    int x = movingBtn->x();
    int y = movingBtn->y();

    int verticalCenterValue = int(this->width()/2) - int(movingBtn->width()/2);
    int horizontalCenterValue = int(this->width()/2) - int(movingBtn->height()/2);

    // 判断是否显示中心竖线
    if (x>verticalCenterValue-this->lineShowThresholdValue && x<verticalCenterValue+this->lineShowThresholdValue) {
        this->isVerticalCenterLineShown = true;

        // 判断是否吸附
        if (x>verticalCenterValue-this->lineAdsorbThresholdValue && x<verticalCenterValue+this->lineAdsorbThresholdValue) {
            movingBtn->move(verticalCenterValue, y);
        }
    }
    else {
        this->isVerticalCenterLineShown = false;
    }

    // 判断是否显示中心横线
    if (y>horizontalCenterValue-this->lineShowThresholdValue && y<horizontalCenterValue+this->lineShowThresholdValue) {
        this->isHorizontalCenterLineShown = true;

        // 判断是否吸附
        if (y>horizontalCenterValue-this->lineAdsorbThresholdValue && y<horizontalCenterValue+this->lineAdsorbThresholdValue) {
            movingBtn->move(x, horizontalCenterValue);
        }
    }
    else {
        this->isHorizontalCenterLineShown = false;
    }
}

void Window::changeBtnNum(int newNum) {
    int currentNum = this->btnList.size();

    if (currentNum < newNum) {
        int diff = newNum - currentNum;
        for (int i=0; i<diff; i++) {
            QString text = QString("button%1").arg(currentNum);
            Button *btn = new Button(text, this);
            int x = rand() % (this->width()-btn->width()+1);
            int y = rand() % (this->height()-btn->width()+1);
            btn->move(x, y);
            btn->show();
            this->btnList.append(btn);
        }
    }
    else if (currentNum > newNum) {
        int diff = currentNum - newNum;
        for (int i=0; i<diff; i++) {
            Button *btn = this->btnList.takeLast();
            btn->deleteLater();
        }
    }
}

main.cpp

#include "window.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Window w;
    w.show();
    return a.exec();
}

以上就是Qt实现对齐线功能的示例代码的详细内容,更多关于Qt对齐线的资料请关注编程网其它相关文章!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Qt实现对齐线功能的示例代码

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Android强制下线功能实现的代码示例

强制下线的应用场景很多, 比如我们好多账号都有抢登的显现, 会被挤下线. 详细实现: 其实实现强制下线功能的思路也比较简单, 只需要在界面弹出一个对话框, 让用户无法进行其他操作, 必须点击对话框中的确定按钮, 然后回到登录界面即可. 但是
2022-06-06

Qt实现http服务的示例代码

这篇文章将为大家详细讲解有关Qt如何实现http服务,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获
2023-05-15

Python实现录屏功能的示例代码

这篇文章主要为大家详细介绍了如何利用Python实现录屏功能,文中的示例代码讲解详细,对我们掌握Python开发有一定的帮助,需要的可以参考一下
2023-03-24

Spring AOP实现功能权限校验功能的示例代码

实现功能权限校验的功能有多种方法,其一使用拦截器拦截请求,其二是使用AOP抛异常。 首先用拦截器实现未登录时跳转到登录界面的功能。注意这里没有使用AOP切入,而是用拦截器拦截,因为AOP一般切入的是service层方法,而拦截器是拦截控制器
2023-05-30

VuePC端实现扫码登录功能示例代码

目前大多数PC端应用都有配套的移动端APP,如微信,淘宝等,通过使用手机APP上的扫一扫功能去扫页面二维码图片进行登录,使得用户登录操作更方便,安全,快捷,这篇文章主要介绍了VuePC端如何实现扫码登录功能,需要的朋友可以参考下
2023-01-28

Vue3+axios+Mock.js实现登录功能的示例代码

本文主要介绍了Vue3+axios+Mock.js实现登录功能的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
2023-05-19

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录