iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >Qt实现对齐线功能的示例代码
  • 739
分享到

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

2024-04-02 19:04:59 739人浏览 薄情痞子
摘要

目录现有功能运行结果源码button.hbutton.cppwindow.hwindow.cppmain.cpp现有功能 1.添加任意数量的按钮。 2.移动按钮,通过对齐线来设置按钮

现有功能

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对齐线的资料请关注编程网其它相关文章!

--结束END--

本文标题: Qt实现对齐线功能的示例代码

本文链接: https://www.lsjlt.com/news/150776.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

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

下载Word文档
猜你喜欢
  • c语言怎么计算字符串长度
    在C语言中,可以使用内置的strlen()函数来计算字符串的长度。该函数位于string.h头文件中。以下是一个示例代码: #inc...
    99+
    2024-05-14
    c语言
  • c语言怎么判断三个数的大小
    可以通过比较三个数之间的大小关系来判断它们的大小。以下是一个示例代码: #include <stdio.h> int ...
    99+
    2024-05-14
    c语言
  • c++排序函数sort怎么使用
    在C++中,使用sort函数对容器中的元素进行排序,可以按照默认的升序排列,也可以自定义排序规则。 下面是一个简单的例子,对一个ve...
    99+
    2024-05-14
    c++
  • c++中string的compare函数怎么使用
    在C++中,可以使用string的compare函数来比较两个string对象的大小。该函数的原型如下: int compare(c...
    99+
    2024-05-14
    c++
  • c++中string的compare函数有什么用
    c++中string的compare函数用于比较两个字符串的大小关系。该函数返回一个整数值,表示两个字符串的比较结果。 具体来说,如...
    99+
    2024-05-14
    c++
  • c++中print函数的功能有哪些
    在C++中,通常使用std::cout来进行输出操作,而不是使用print函数。std::cout是C++标准库中的一个输出流对象,...
    99+
    2024-05-14
    c++
  • c语言数据结构怎么使用
    在C语言中,数据结构可以通过定义结构体来实现。以下是一些常见的数据结构的使用方法示例: 链表: #include <std...
    99+
    2024-05-14
    c语言
  • c++中print函数的用法是什么
    在C++中没有内置的print函数,但可以使用cout来输出内容到控制台。cout是C++标准库中的一个输出流对象,可以使用<...
    99+
    2024-05-14
    c++
  • c++中concept的用法是什么
    在C++20中,Concept是一种新的语言特性,用于定义类型要求和约束。Concept可以被用来约束函数模板、类模板和普通函数的参...
    99+
    2024-05-14
    c++
  • c++中concept的作用是什么
    在C++中,concept的作用是定义一种通用的约束,用于限制模板参数的类型范围。通过使用concept,可以在编译时对模板参数进行...
    99+
    2024-05-14
    c++
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作