Qt實現(xiàn)對齊線功能的示例代碼
更新時間:2022年06月07日 14:45:20 作者:la_vie_est_belle
這篇文章主要介紹了Qt如何實現(xiàn)對齊線功能,并且可以添加任意數(shù)量和自動吸附,文中示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
現(xiàn)有功能
1.添加任意數(shù)量的按鈕。
2.移動按鈕,通過對齊線來設(shè)置按鈕位置。
3.自動吸附。
運行結(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); // 繪制垂直中心線 void drawHorizontalCenterLine(QPainter &painter); // 繪制水平中心線 void drawBtnLeftLine(QPainter &painter); // 繪制按鈕左側(cè)線 void drawBtnTopLine(QPainter &painter); // 繪制按鈕頂部線 void checkBtnTopLine(Button *movingBtn); // 比對當前移動按鈕和其他按鈕頂部的位置 void checkBtnLeftLine(Button *movingBtn); // 比對當前移動按鈕和其他按鈕左側(cè)的位置 void checkWindowCenterLines(Button *movingBtn); // 比對按鈕和中心線的位置 private: QSpinBox *spinBox; QList<Button *> btnList; int lineShowThresholdValue; // 線條顯示閾值 int lineAdsorbThresholdValue; // 線條吸附閾值 bool isVerticalCenterLineShown; // 是否顯示中心豎線 bool isHorizontalCenterLineShown; // 是否顯示中心橫線 bool isBtnLeftLineShown; // 是否顯示按鈕左側(cè)線條 bool isBtnTopLineShown; // 是否顯示按鈕頂部線條 int btnLeftLineX; // 按鈕左側(cè)線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實現(xiàn)對齊線功能的示例代碼的詳細內(nèi)容,更多關(guān)于Qt對齊線的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
C++實現(xiàn)LeetCode(97.交織相錯的字符串)
這篇文章主要介紹了C++實現(xiàn)LeetCode(97.交織相錯的字符串),本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下2021-07-07C語言實現(xiàn)手寫Map(數(shù)組+鏈表+紅黑樹)的示例代碼
這篇文章主要為大家詳細介紹了如何利用C語言實現(xiàn)手寫Map(數(shù)組+鏈表+紅黑樹),文中的示例代碼講解詳細,對我們學(xué)習(xí)有一定借鑒價值,需要的可以參考一下2022-09-09詳解C語言中g(shù)etgid()函數(shù)和getegid()函數(shù)的區(qū)別
這篇文章主要介紹了詳解C語言中g(shù)etgid()函數(shù)和getegid()函數(shù)的區(qū)別,注意getegid只返回有效的組識別碼,需要的朋友可以參考下2015-08-08