亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Qt實(shí)現(xiàn)對(duì)齊線(xiàn)功能的示例代碼

 更新時(shí)間:2022年06月07日 14:45:20   作者:la_vie_est_belle  
這篇文章主要介紹了Qt如何實(shí)現(xiàn)對(duì)齊線(xiàn)功能,并且可以添加任意數(shù)量和自動(dòng)吸附,文中示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下

現(xiàn)有功能

1.添加任意數(shù)量的按鈕。

2.移動(dòng)按鈕,通過(guò)對(duì)齊線(xiàn)來(lái)設(shè)置按鈕位置。

3.自動(dòng)吸附。

運(yùn)行結(jié)果

源碼

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);                      // 改變按鈕數(shù)量

private:
    void drawVerticalCenterLine(QPainter &painter);     // 繪制垂直中心線(xiàn)
    void drawHorizontalCenterLine(QPainter &painter);   // 繪制水平中心線(xiàn)
    void drawBtnLeftLine(QPainter &painter);            // 繪制按鈕左側(cè)線(xiàn)
    void drawBtnTopLine(QPainter &painter);             // 繪制按鈕頂部線(xiàn)
    void checkBtnTopLine(Button *movingBtn);            // 比對(duì)當(dāng)前移動(dòng)按鈕和其他按鈕頂部的位置
    void checkBtnLeftLine(Button *movingBtn);           // 比對(duì)當(dāng)前移動(dòng)按鈕和其他按鈕左側(cè)的位置
    void checkWindowCenterLines(Button *movingBtn);     // 比對(duì)按鈕和中心線(xiàn)的位置

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

    int lineShowThresholdValue;                         // 線(xiàn)條顯示閾值
    int lineAdsorbThresholdValue;                       // 線(xiàn)條吸附閾值
    bool isVerticalCenterLineShown;                     // 是否顯示中心豎線(xiàn)
    bool isHorizontalCenterLineShown;                   // 是否顯示中心橫線(xiàn)
    bool isBtnLeftLineShown;                            // 是否顯示按鈕左側(cè)線(xiàn)條
    bool isBtnTopLineShown;                             // 是否顯示按鈕頂部線(xiàn)條

    int btnLeftLineX;                                   // 按鈕左側(cè)線(xiàn)x坐標(biāo)
    int btnTopLineY;                                    // 按鈕頂部線(xiàn)y坐標(biāo)

    QPen pen1;                                          // 用來(lái)繪制中心對(duì)齊線(xiàn)
    QPen pen2;                                          // 用來(lái)繪制按鈕間的對(duì)齊線(xiàn)
};
#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);

    // 判斷是否顯示中心豎線(xiàn)
    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;
    }

    // 判斷是否顯示中心橫線(xiàn)
    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實(shí)現(xiàn)對(duì)齊線(xiàn)功能的示例代碼的詳細(xì)內(nèi)容,更多關(guān)于Qt對(duì)齊線(xiàn)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • C++實(shí)現(xiàn)LeetCode(97.交織相錯(cuò)的字符串)

    C++實(shí)現(xiàn)LeetCode(97.交織相錯(cuò)的字符串)

    這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(97.交織相錯(cuò)的字符串),本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • C語(yǔ)言實(shí)現(xiàn)手寫(xiě)Map(數(shù)組+鏈表+紅黑樹(shù))的示例代碼

    C語(yǔ)言實(shí)現(xiàn)手寫(xiě)Map(數(shù)組+鏈表+紅黑樹(shù))的示例代碼

    這篇文章主要為大家詳細(xì)介紹了如何利用C語(yǔ)言實(shí)現(xiàn)手寫(xiě)Map(數(shù)組+鏈表+紅黑樹(shù)),文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)有一定借鑒價(jià)值,需要的可以參考一下
    2022-09-09
  • C語(yǔ)言繪制三角函數(shù)曲線(xiàn)

    C語(yǔ)言繪制三角函數(shù)曲線(xiàn)

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言繪制三角函數(shù)曲線(xiàn),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-06-06
  • C++頭文件algorithm中的函數(shù)功能詳解

    C++頭文件algorithm中的函數(shù)功能詳解

    這篇文章主要介紹了C++頭文件algorithm中的函數(shù)功能詳解,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-04-04
  • 詳解C++中的指針、數(shù)組指針與函數(shù)指針

    詳解C++中的指針、數(shù)組指針與函數(shù)指針

    本文從初學(xué)者的角度,深入淺出地講解C++中的指針、數(shù)組指針與函數(shù)指針,對(duì)最?;煜囊脗鬟f、值傳遞和指針傳遞做了區(qū)處,需要的朋友可以參考下
    2015-07-07
  • OpenCV實(shí)現(xiàn)直線(xiàn)檢測(cè)并消除

    OpenCV實(shí)現(xiàn)直線(xiàn)檢測(cè)并消除

    這篇文章主要為大家詳細(xì)介紹了OpenCV實(shí)現(xiàn)直線(xiàn)檢測(cè)并消除,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-06-06
  • c語(yǔ)言描述回文數(shù)的三種算法

    c語(yǔ)言描述回文數(shù)的三種算法

    這篇文章主要介紹了c語(yǔ)言描述回文數(shù)的三種算法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-04-04
  • 詳解C語(yǔ)言中g(shù)etgid()函數(shù)和getegid()函數(shù)的區(qū)別

    詳解C語(yǔ)言中g(shù)etgid()函數(shù)和getegid()函數(shù)的區(qū)別

    這篇文章主要介紹了詳解C語(yǔ)言中g(shù)etgid()函數(shù)和getegid()函數(shù)的區(qū)別,注意getegid只返回有效的組識(shí)別碼,需要的朋友可以參考下
    2015-08-08
  • C++之談?wù)剺?gòu)造函數(shù)的初始化列表

    C++之談?wù)剺?gòu)造函數(shù)的初始化列表

    構(gòu)造函數(shù)主要作用在于創(chuàng)建對(duì)象時(shí)為對(duì)象的成員屬性賦值,構(gòu)造函數(shù)由編譯器自動(dòng)調(diào)用,無(wú)須手動(dòng)調(diào)用,這篇文章詳細(xì)介紹了構(gòu)造函數(shù)的初始化列表,文章中有詳細(xì)的示例代碼,感興趣的同學(xué)可以參考閱讀
    2023-04-04
  • C++解析特殊符號(hào)tab和換行符號(hào)詳情

    C++解析特殊符號(hào)tab和換行符號(hào)詳情

    這篇文章主要給大家介紹的是C++解析一些特殊符號(hào)tab、換行符號(hào)的一些相關(guān)資料,需要的小伙伴可以參考下面文章的具體內(nèi)容
    2021-09-09

最新評(píng)論