From fe7a7ad1b9bdb6b7091034537dd36b55dc7938dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B5=AE=E7=94=9F=E8=8B=A5=E6=A2=A6?= <1070753498@qq.com> Date: Wed, 5 Jul 2023 18:47:19 +0800 Subject: [PATCH] tableview; clang-tidy; --- .clang-tidy | 60 ++++++ Battery/batterywidget.cpp | 40 ++-- Battery/batterywidget.h | 30 +-- Battery/main.cpp | 2 +- Battery/mainwindow.cpp | 5 +- Battery/mainwindow.h | 2 +- BubbleWindow/bubblewidget.cpp | 45 +++-- BubbleWindow/bubblewidget.h | 14 +- BubbleWindow/main.cpp | 2 +- Chart/CMakeLists.txt | 52 +++-- Chart/Chart.pro | 2 - Chart/areachart.cpp | 19 +- Chart/areachart.h | 2 +- Chart/callout.cpp | 37 ++-- Chart/callout.h | 10 +- Chart/chartlabel.cpp | 7 - Chart/chartlabel.h | 12 -- Chart/chartview.cpp | 33 +--- Chart/datetimechart.cpp | 20 +- Chart/datetimechart.h | 2 +- Chart/dialogchart.cpp | 16 +- Chart/dialogchart.h | 2 +- Chart/dynamicchart.cpp | 12 +- Chart/dynamicchartx.cpp | 58 +++--- Chart/dynamicchartx.h | 7 +- Chart/linechart.cpp | 79 ++++---- Chart/linechart.h | 7 +- Chart/main.cpp | 2 +- Chart/mainwindow.cpp | 11 +- Chart/mainwindow.h | 5 +- Chart/normalchartdata.cpp | 7 +- Chart/normalchartdata.h | 7 +- Chart/piechart.cpp | 29 +-- Chart/piechart.h | 9 +- Chart/stackedbarchart.cpp | 27 +-- Chart/stackedbarchart.h | 9 +- CheckBoxStandardItem/main.cc | 2 +- CheckBoxStandardItem/mainwindow.hpp | 14 +- Clock/clockwidget.cpp | 120 ++++++------ Clock/clockwidget.h | 24 +-- Clock/main.cpp | 2 +- Clock/mainwindow.cpp | 5 +- Clock/mainwindow.h | 4 +- DashBoard/dashboardwidget.cpp | 178 +++++++++--------- DashBoard/dashboardwidget.h | 38 ++-- DashBoard/main.cpp | 2 +- DashBoard/mainwindow.h | 4 +- DragDrop/draglistwidget.cpp | 6 +- DragDrop/draglistwidget.h | 2 +- DragDrop/droplistwidget.cpp | 13 +- DragDrop/droplistwidget.h | 5 +- DragDrop/main.cpp | 2 +- DragDrop/mainwindow.h | 2 +- FlowLayout/flowlayout.cpp | 55 +++--- FlowLayout/flowlayout.h | 26 +-- FlowLayout/flowwidget.cc | 6 +- FlowLayout/flowwidget.hpp | 6 +- FlowLayout/main.cc | 2 +- FlowLayout/mainwindow.hpp | 13 +- GridViewModel/gridmodel.cpp | 14 +- GridViewModel/gridmodel.h | 19 +- GridViewModel/gridview.cpp | 8 +- GridViewModel/gridview.h | 8 +- GridViewModel/main.cpp | 2 +- GridViewModel/mainwindow.h | 4 +- HttpClient/httpclient.cpp | 147 +++++++++------ HttpClient/httpclient.h | 14 +- HttpClient/httpclientthread.cpp | 20 +- HttpClient/httpclientthread.h | 14 +- HttpClient/main.cpp | 2 +- HttpClient/mainwindow.cpp | 25 ++- HttpClient/mainwindow.h | 4 +- LogAsynchronous/fileutil.cpp | 12 +- LogAsynchronous/fileutil.h | 6 +- LogAsynchronous/logasync.cpp | 9 +- LogAsynchronous/logasync.h | 8 +- LogAsynchronous/main.cpp | 2 +- LogAsynchronous/mainwindow.h | 4 +- MulClient/main.cpp | 2 +- MulClient/mainwindow.cpp | 2 +- MulClient/mainwindow.h | 6 +- MulClient/tcpclient.cpp | 2 +- MulClient/tcpclient.h | 8 +- MulClient/tcpclientthread.cpp | 2 +- MulClient/tcpclientthread.h | 6 +- MulServer/accepter.h | 2 +- MulServer/main.cpp | 2 +- MulServer/mainwindow.cpp | 2 +- MulServer/mainwindow.h | 4 +- MulServer/tcpclient.cpp | 2 +- MulServer/tcpclient.h | 6 +- MulServer/tcpserver.h | 2 +- MulServer/thread.h | 2 +- NavigationProgressBar/main.cpp | 2 +- NavigationProgressBar/mainwindow.h | 4 +- .../navigationprogressbar.cpp | 55 +++--- NavigationProgressBar/navigationprogressbar.h | 16 +- PasswordLineEdit/main.cc | 2 +- PasswordLineEdit/mainwindow.hpp | 4 +- ProgressArc/main.cpp | 2 +- ProgressArc/mainwindow.h | 4 +- ProgressArc/progressarc.cpp | 37 ++-- ProgressArc/progressarc.h | 30 +-- ProgressBar/main.cc | 2 +- ProgressBar/mainwindow.hpp | 4 +- ProgressBar/progressbar.cc | 33 ++-- ProgressBar/progressbar.hpp | 26 +-- README.md | 62 +++--- ReactorServer/main.cpp | 2 +- ReactorServer/mainwindow.cpp | 2 +- ReactorServer/mainwindow.h | 4 +- ReactorServer/subreactor.h | 4 +- ReactorServer/tcpclient.cpp | 2 +- ReactorServer/tcpclient.h | 6 +- ReactorServer/tcpserver.cpp | 40 ++-- ReactorServer/tcpserver.h | 4 +- ReactorServer/thread.h | 2 +- SlipButton/main.cpp | 2 +- SlipButton/mainwindow.h | 4 +- SlipButton/slipbutton.h | 28 +-- SqlTabview/main.cpp | 2 +- SqlTabview/mainwindow.cpp | 2 +- SqlTabview/mainwindow.h | 4 +- SqlTabview/sql.h | 4 +- TableViewModel/CMakeLists.txt | 44 +++-- TableViewModel/TableViewModel.pro | 16 +- TableViewModel/buttondelegate.cpp | 48 ++--- TableViewModel/buttondelegate.h | 8 +- TableViewModel/comboboxdelegate.cpp | 11 +- TableViewModel/comboboxdelegate.h | 4 +- TableViewModel/displaydata.hpp | 84 +++++++++ TableViewModel/displaytablemodel.cc | 125 ++++++++++++ TableViewModel/displaytablemodel.hpp | 42 +++++ TableViewModel/displaytableview.cc | 79 ++++++++ TableViewModel/displaytableview.hpp | 26 +++ TableViewModel/main.cpp | 13 +- TableViewModel/mainwindow.cpp | 113 ++++++----- TableViewModel/mainwindow.h | 13 +- .../picture/TabViewModelDelegate.jpg | Bin 0 -> 162549 bytes .../picture/TabViewModelDelegate.png | Bin 11233 -> 0 bytes TableViewModel/progressbardelegate.h | 4 +- TableViewModel/richtextitemdelegate.cc | 10 +- TableViewModel/richtextitemdelegate.hpp | 3 +- TableViewModel/sortfilterproxymodel.cpp | 2 +- TableViewModel/sortfilterproxymodel.h | 8 +- TableViewModel/stardelegate.cpp | 90 +++++++++ TableViewModel/stardelegate.h | 31 +++ TableViewModel/stareditor.cpp | 63 +++++++ TableViewModel/stareditor.h | 39 ++++ TableViewModel/starrating.cpp | 60 ++++++ TableViewModel/starrating.h | 39 ++++ TableViewModel/student.h | 91 --------- TableViewModel/studenttablemodel.cpp | 126 ------------- TableViewModel/studenttablemodel.h | 28 --- TableViewModel/stuedenttable.cpp | 60 ------ TableViewModel/stuedenttable.h | 33 ---- Thread/functions.hpp | 2 +- Thread/main.cc | 2 +- Thread/task.hpp | 2 +- Thread/thread.hpp | 8 +- TreeViewModel/checkboxheaderview.hpp | 2 +- TreeViewModel/fileinfo.cc | 2 +- TreeViewModel/fileinfo.hpp | 24 +-- TreeViewModel/fileitem.hpp | 12 +- TreeViewModel/listview.hpp | 2 +- TreeViewModel/main.cc | 2 +- TreeViewModel/mainwindow.hpp | 6 +- TreeViewModel/normaltreeview.cc | 11 +- TreeViewModel/normaltreeview.hpp | 12 +- TreeViewModel/treemodel.cc | 78 ++++---- TreeViewModel/treemodel.hpp | 84 +++++---- TreeViewModel/treeview.cc | 6 +- TreeViewModel/treeview.hpp | 8 +- Validator/main.cc | 2 +- Validator/mainwindow.hpp | 15 +- Validator/validator.cc | 4 +- Validator/validator.hpp | 4 +- 177 files changed, 2012 insertions(+), 1570 deletions(-) create mode 100644 .clang-tidy delete mode 100644 Chart/chartlabel.cpp delete mode 100644 Chart/chartlabel.h create mode 100644 TableViewModel/displaydata.hpp create mode 100644 TableViewModel/displaytablemodel.cc create mode 100644 TableViewModel/displaytablemodel.hpp create mode 100644 TableViewModel/displaytableview.cc create mode 100644 TableViewModel/displaytableview.hpp create mode 100644 TableViewModel/picture/TabViewModelDelegate.jpg delete mode 100644 TableViewModel/picture/TabViewModelDelegate.png create mode 100644 TableViewModel/stardelegate.cpp create mode 100644 TableViewModel/stardelegate.h create mode 100644 TableViewModel/stareditor.cpp create mode 100644 TableViewModel/stareditor.h create mode 100644 TableViewModel/starrating.cpp create mode 100644 TableViewModel/starrating.h delete mode 100644 TableViewModel/student.h delete mode 100644 TableViewModel/studenttablemodel.cpp delete mode 100644 TableViewModel/studenttablemodel.h delete mode 100644 TableViewModel/stuedenttable.cpp delete mode 100644 TableViewModel/stuedenttable.h diff --git a/.clang-tidy b/.clang-tidy new file mode 100644 index 0000000..f95ff5f --- /dev/null +++ b/.clang-tidy @@ -0,0 +1,60 @@ +--- +Checks: '-*,clang-analyzer-*,readability-*,performance-*,modernize-*,bugprone-*,cert-,cppcoreguidelines-,portability-*,llvm-*,google-*' +WarningsAsErrors: '' +HeaderFilterRegex: '.' +AnalyzeTemporaryDtors: false +FormatStyle: file +User: user +CheckOptions: + - key: readability-identifier-naming.AbstractClassCase + value: CamelCase + - key: readability-identifier-naming.ClassCase + value: CamelCase + - key: readability-identifier-naming.ClassConstantCase + value: UPPER_CASE + - key: readability-identifier-naming.ClassConstantPrefix + value: 'k' + - key: readability-identifier-naming.ClassMemberCase + value: lower_case + - key: readability-identifier-naming.ClassMemberPrefix + value: 'm_' + - key: readability-identifier-naming.ClassMethodCase + value: camelBack + - key: readability-identifier-naming.ConstexprVariableCase + value: UPPER_CASE + - key: readability-identifier-naming.ConstexprVariablePrefix + value: 'k' + - key: readability-identifier-naming.EnumCase + value: CamelCase + - key: readability-identifier-naming.EnumConstantCase + value: UPPER_CASE + - key: readability-identifier-naming.EnumConstantPrefix + value: '' + - key: readability-identifier-naming.FunctionCase + value: camelBack + - key: readability-identifier-naming.FunctionParameterCase + value: lower_case + - key: readability-identifier-naming.GlobalConstantCase + value: UPPER_CASE + - key: readability-identifier-naming.GlobalConstantPrefix + value: 'k' + - key: readability-identifier-naming.GlobalFunctionCase + value: camelBack + - key: readability-identifier-naming.GlobalVariableCase + value: lower_case + - key: readability-identifier-naming.GlobalVariablePrefix + value: 'g_' + - key: readability-identifier-naming.InlineNamespaceCase + value: lower_case + - key: readability-identifier-naming.LocalConstantCase + value: UPPER_CASE + - key: readability-identifier-naming.LocalConstantPrefix + value: 'k' + - key: readability-identifier-naming.LocalVariableCase + value: lower_case + - key: readability-identifier-naming.MacroDefinitionCase + value: UPPER_CASE + - key: readability-identifier-naming.NamespaceCase + value: lower_case + - key: bugprone-narrowing-conversions.IgnoreFloatingPointPrecisionLoss + value: 'false' diff --git a/Battery/batterywidget.cpp b/Battery/batterywidget.cpp index 7e2f881..52305e9 100644 --- a/Battery/batterywidget.cpp +++ b/Battery/batterywidget.cpp @@ -25,9 +25,7 @@ BatteryWidget::BatteryWidget(QWidget *parent) connect(this, &BatteryWidget::valueChanged, this, &BatteryWidget::onStartAnimation); } -BatteryWidget::~BatteryWidget() -{ -} +BatteryWidget::~BatteryWidget() = default; void BatteryWidget::setBorderColor(const QColor &color) { @@ -35,7 +33,7 @@ void BatteryWidget::setBorderColor(const QColor &color) update(); } -QColor BatteryWidget::borderColor() const +auto BatteryWidget::borderColor() const -> QColor { return d_ptr->borderColor; } @@ -46,7 +44,7 @@ void BatteryWidget::setPowerColor(const QColor &color) update(); } -QColor BatteryWidget::powerColor() const +auto BatteryWidget::powerColor() const -> QColor { return d_ptr->powerColor; } @@ -57,19 +55,19 @@ void BatteryWidget::setAlarmColor(const QColor &color) update(); } -QColor BatteryWidget::alarmColor() const +auto BatteryWidget::alarmColor() const -> QColor { return d_ptr->alarmColor; } -QSize BatteryWidget::sizeHint() const +auto BatteryWidget::sizeHint() const -> QSize { - return QSize(150, 80); + return {150, 80}; } -QSize BatteryWidget::minimumSizeHint() const +auto BatteryWidget::minimumSizeHint() const -> QSize { - return QSize(80, 45); + return {80, 45}; } void BatteryWidget::paintEvent(QPaintEvent *event) @@ -99,8 +97,9 @@ void BatteryWidget::paintEvent(QPaintEvent *event) void BatteryWidget::onStartAnimation(const int value) { - if (value == d_ptr->value) + if (value == d_ptr->value) { return; + } int start = d_ptr->value; int end = value; @@ -110,22 +109,20 @@ void BatteryWidget::onStartAnimation(const int value) d_ptr->animation->start(); } -int BatteryWidget::value() const +auto BatteryWidget::value() const -> int { return d_ptr->value; } -void BatteryWidget::setValue(const int value) +void BatteryWidget::setValue(int value) { - if (value == d_ptr->value) + Q_ASSERT(value >= 0 && value <= 100); + + if (value == d_ptr->value) { return; + } - if(value < 0) - d_ptr->value = 0; - else if(value > 100) - d_ptr->value = 100; - else - d_ptr->value = value; + d_ptr->value = value; update(); } @@ -144,8 +141,7 @@ void BatteryWidget::drawPower(QPainter *painter, const QRectF &batteryRect, cons double margin = qMin(width(), height()) / 50.0; margin = qMax(margin, linew); qreal unit = (batteryRect.width() - (margin * 2)) / 100; - QPointF topLeft(batteryRect.topLeft().x() + margin, - batteryRect.topLeft().y() + margin); + QPointF topLeft(batteryRect.topLeft().x() + margin, batteryRect.topLeft().y() + margin); QPointF bottomRight(d_ptr->value * unit + margin + 5, batteryRect.bottomRight().y() - margin); QRectF rect(topLeft, bottomRight); double bgRadius = rect.height() / 30; diff --git a/Battery/batterywidget.h b/Battery/batterywidget.h index 462394f..942cd5c 100644 --- a/Battery/batterywidget.h +++ b/Battery/batterywidget.h @@ -12,35 +12,35 @@ class BatteryWidget : public QWidget Q_PROPERTY(QColor alarmColor READ alarmColor WRITE setAlarmColor) public: explicit BatteryWidget(QWidget *parent = nullptr); - ~BatteryWidget(); + ~BatteryWidget() override; - QSize sizeHint() const override; - QSize minimumSizeHint() const override; + [[nodiscard]] [[nodiscard]] auto sizeHint() const -> QSize override; + [[nodiscard]] [[nodiscard]] auto minimumSizeHint() const -> QSize override; - void setBorderColor(const QColor& color); - QColor borderColor() const; + void setBorderColor(const QColor &color); + [[nodiscard]] [[nodiscard]] auto borderColor() const -> QColor; - void setPowerColor(const QColor& color); - QColor powerColor() const; + void setPowerColor(const QColor &color); + [[nodiscard]] [[nodiscard]] auto powerColor() const -> QColor; - void setAlarmColor(const QColor& color); - QColor alarmColor() const; + void setAlarmColor(const QColor &color); + [[nodiscard]] [[nodiscard]] auto alarmColor() const -> QColor; - void setValue(const int value); - int value() const; + void setValue(int value); + [[nodiscard]] [[nodiscard]] auto value() const -> int; signals: - void valueChanged(const int value); + void valueChanged(int value); private slots: - void onStartAnimation(const int value); + void onStartAnimation(int value); protected: void paintEvent(QPaintEvent *event) override; private: - void drawBorder(QPainter *painter, const QRectF &batteryRect, const double linew); - void drawPower(QPainter *painter, const QRectF &batteryRect, const double linew); + void drawBorder(QPainter *painter, const QRectF &batteryRect, double linew); + void drawPower(QPainter *painter, const QRectF &batteryRect, double linew); void drawValue(QPainter *painter, const QRectF &batteryRect); void drawHeader(QPainter *painter, const QRectF &batteryRect); diff --git a/Battery/main.cpp b/Battery/main.cpp index fd3e533..24ba3b6 100644 --- a/Battery/main.cpp +++ b/Battery/main.cpp @@ -2,7 +2,7 @@ #include -int main(int argc, char *argv[]) +auto main(int argc, char *argv[]) -> int { QApplication a(argc, argv); MainWindow w; diff --git a/Battery/mainwindow.cpp b/Battery/mainwindow.cpp index 6344b62..c14910d 100644 --- a/Battery/mainwindow.cpp +++ b/Battery/mainwindow.cpp @@ -19,7 +19,4 @@ MainWindow::MainWindow(QWidget *parent) resize(300, 160); } -MainWindow::~MainWindow() -{ -} - +MainWindow::~MainWindow() {} diff --git a/Battery/mainwindow.h b/Battery/mainwindow.h index eb5f430..ffddf4a 100644 --- a/Battery/mainwindow.h +++ b/Battery/mainwindow.h @@ -8,6 +8,6 @@ class MainWindow : public QMainWindow Q_OBJECT public: explicit MainWindow(QWidget *parent = nullptr); - ~MainWindow(); + ~MainWindow() override; }; #endif // MAINWINDOW_H diff --git a/BubbleWindow/bubblewidget.cpp b/BubbleWindow/bubblewidget.cpp index 150b485..03fe409 100644 --- a/BubbleWindow/bubblewidget.cpp +++ b/BubbleWindow/bubblewidget.cpp @@ -2,7 +2,8 @@ #include -struct Triangle{ +struct Triangle +{ int width = 10; int height = 10; BubbleWidget::Direction direct = BubbleWidget::Direction::Top; @@ -12,17 +13,20 @@ class BubbleWidget::BubbleWidgetPrivate { public: BubbleWidgetPrivate(QWidget *parent) - : owner(parent){ - shadowEffect = new QGraphicsDropShadowEffect(owner); + : q_ptr(parent) + { + shadowEffect = new QGraphicsDropShadowEffect(q_ptr); shadowEffect->setOffset(0, 0); shadowEffect->setColor(Qt::gray); shadowEffect->setBlurRadius(shadowWidth); - centralWidget = new QWidget(owner); + centralWidget = new QWidget(q_ptr); pen.setWidth(2); } - QWidget *owner; - QGraphicsDropShadowEffect* shadowEffect; + + QWidget *q_ptr; + + QGraphicsDropShadowEffect *shadowEffect; QWidget *centralWidget; Triangle triangle; @@ -45,10 +49,7 @@ BubbleWidget::BubbleWidget(QWidget *parent) resize(200, 100); } -BubbleWidget::~BubbleWidget() -{ - -} +BubbleWidget::~BubbleWidget() {} void BubbleWidget::setPen(const QPen &pen) { @@ -142,25 +143,28 @@ void BubbleWidget::paintEvent(QPaintEvent *) QPainterPath drawPath; QPolygon trianglePolygon; QRect rect; - switch (d_ptr->triangle.direct) - { + switch (d_ptr->triangle.direct) { case Top: trianglePolygon << QPoint(width() / 2, d_ptr->shadowWidth); trianglePolygon << QPoint(width() / 2 + d_ptr->triangle.width / 2, d_ptr->triangle.height + d_ptr->shadowWidth); trianglePolygon << QPoint(width() / 2 - d_ptr->triangle.width / 2, d_ptr->triangle.height + d_ptr->shadowWidth); - rect = QRect(d_ptr->shadowWidth, d_ptr->triangle.height + d_ptr->shadowWidth, + rect = QRect(d_ptr->shadowWidth, + d_ptr->triangle.height + d_ptr->shadowWidth, width() - d_ptr->shadowWidth * 2, height() - d_ptr->shadowWidth * 2 - d_ptr->triangle.height); drawPath.addRoundedRect(rect, d_ptr->borderRadius, d_ptr->borderRadius); break; case Left: - trianglePolygon << QPoint(d_ptr->shadowWidth, d_ptr->triangle.height + d_ptr->shadowWidth + d_ptr->shadowWidth); - trianglePolygon << QPoint(d_ptr->shadowWidth + d_ptr->triangle.width, d_ptr->shadowWidth + d_ptr->shadowWidth); + trianglePolygon << QPoint(d_ptr->shadowWidth, + d_ptr->triangle.height + d_ptr->shadowWidth + d_ptr->shadowWidth); + trianglePolygon << QPoint(d_ptr->shadowWidth + d_ptr->triangle.width, + d_ptr->shadowWidth + d_ptr->shadowWidth); trianglePolygon << QPoint(d_ptr->shadowWidth + d_ptr->triangle.width, d_ptr->triangle.height + d_ptr->shadowWidth + d_ptr->shadowWidth); - rect = QRect(d_ptr->shadowWidth + d_ptr->triangle.width, d_ptr->shadowWidth, + rect = QRect(d_ptr->shadowWidth + d_ptr->triangle.width, + d_ptr->shadowWidth, width() - d_ptr->shadowWidth * 2 - d_ptr->triangle.width, height() - d_ptr->shadowWidth * 2); drawPath.addRoundedRect(rect, d_ptr->borderRadius, d_ptr->borderRadius); @@ -172,7 +176,8 @@ void BubbleWidget::paintEvent(QPaintEvent *) d_ptr->triangle.height + d_ptr->shadowWidth + d_ptr->shadowWidth); trianglePolygon << QPoint(width() - d_ptr->shadowWidth, d_ptr->triangle.height + d_ptr->shadowWidth + d_ptr->shadowWidth); - rect = QRect(d_ptr->shadowWidth, d_ptr->shadowWidth, + rect = QRect(d_ptr->shadowWidth, + d_ptr->shadowWidth, width() - d_ptr->shadowWidth * 2 - d_ptr->triangle.width, height() - d_ptr->shadowWidth * 2); drawPath.addRoundedRect(rect, d_ptr->borderRadius, d_ptr->borderRadius); @@ -184,7 +189,9 @@ void BubbleWidget::paintEvent(QPaintEvent *) height() - d_ptr->shadowWidth - d_ptr->triangle.height); trianglePolygon << QPoint(width() / 2 - d_ptr->triangle.width / 2, height() - d_ptr->shadowWidth - d_ptr->triangle.height); - rect = QRect(d_ptr->shadowWidth, d_ptr->shadowWidth, width() - d_ptr->shadowWidth * 2, + rect = QRect(d_ptr->shadowWidth, + d_ptr->shadowWidth, + width() - d_ptr->shadowWidth * 2, height() - d_ptr->shadowWidth * 2 - d_ptr->triangle.height); drawPath.addRoundedRect(rect, d_ptr->borderRadius, d_ptr->borderRadius); break; @@ -193,8 +200,6 @@ void BubbleWidget::paintEvent(QPaintEvent *) drawPath = drawPath.simplified(); painter.drawPath(drawPath); - - painter.setFont(QFont("Microsoft YaHei", 11, 500)); rect = rect.adjusted(5, 5, -5, -5); painter.drawText(rect, Qt::AlignCenter, d_ptr->text); diff --git a/BubbleWindow/bubblewidget.h b/BubbleWindow/bubblewidget.h index cabe1e1..32431d6 100644 --- a/BubbleWindow/bubblewidget.h +++ b/BubbleWindow/bubblewidget.h @@ -7,31 +7,31 @@ class BubbleWidget : public QWidget { Q_OBJECT public: - enum Direction{ Left, Right, Top, Bottom }; + enum Direction { Left, Right, Top, Bottom }; explicit BubbleWidget(QWidget *parent = nullptr); ~BubbleWidget() override; void setPen(const QPen &pen); - QPen pen() const; + [[nodiscard]] auto pen() const -> QPen; void setBrush(const QBrush &brush); - QBrush brush() const; + [[nodiscard]] auto brush() const -> QBrush; void setShadowWidth(qint64 width); - qint64 shadowWidth(); + auto shadowWidth() -> qint64; void setBorderRadius(qint64 radius); - qint64 borderRadius(); + auto borderRadius() -> qint64; void setText(const QString &text); - QString text() const; + [[nodiscard]] auto text() const -> QString; // 设置小三角宽和高; void setTriangleInfo(int width, int height); void setDerection(Direction); - Direction direction(); + auto direction() -> Direction; void exec(); diff --git a/BubbleWindow/main.cpp b/BubbleWindow/main.cpp index fd3e533..24ba3b6 100644 --- a/BubbleWindow/main.cpp +++ b/BubbleWindow/main.cpp @@ -2,7 +2,7 @@ #include -int main(int argc, char *argv[]) +auto main(int argc, char *argv[]) -> int { QApplication a(argc, argv); MainWindow w; diff --git a/Chart/CMakeLists.txt b/Chart/CMakeLists.txt index c87caf0..4f05fc7 100644 --- a/Chart/CMakeLists.txt +++ b/Chart/CMakeLists.txt @@ -1,31 +1,29 @@ set(PROJECT_SOURCES - main.cpp - mainwindow.cpp - mainwindow.h - areachart.h - areachart.cpp - callout.h - callout.cpp - chartlabel.h - chartlabel.cpp - chartview.h - chartview.cpp - datetimechart.h - datetimechart.cpp - dialogchart.h - dialogchart.cpp - dynamicchart.h - dynamicchart.cpp - dynamicchartx.h - dynamicchartx.cpp - linechart.h - linechart.cpp - normalchartdata.h - normalchartdata.cpp - piechart.h - piechart.cpp - stackedbarchart.h - stackedbarchart.cpp) + main.cpp + mainwindow.cpp + mainwindow.h + areachart.h + areachart.cpp + callout.h + callout.cpp + chartview.h + chartview.cpp + datetimechart.h + datetimechart.cpp + dialogchart.h + dialogchart.cpp + dynamicchart.h + dynamicchart.cpp + dynamicchartx.h + dynamicchartx.cpp + linechart.h + linechart.cpp + normalchartdata.h + normalchartdata.cpp + piechart.h + piechart.cpp + stackedbarchart.h + stackedbarchart.cpp) qt_add_executable(Chart MANUAL_FINALIZATION ${PROJECT_SOURCES}) target_link_libraries(Chart PRIVATE Qt6::Widgets Qt6::Charts) diff --git a/Chart/Chart.pro b/Chart/Chart.pro index 7925dcc..7baf4e6 100644 --- a/Chart/Chart.pro +++ b/Chart/Chart.pro @@ -18,7 +18,6 @@ DEFINES += QT_DEPRECATED_WARNINGS SOURCES += \ areachart.cpp \ callout.cpp \ - chartlabel.cpp \ chartview.cpp \ datetimechart.cpp \ dialogchart.cpp \ @@ -34,7 +33,6 @@ SOURCES += \ HEADERS += \ areachart.h \ callout.h \ - chartlabel.h \ chartview.h \ datetimechart.h \ dialogchart.h \ diff --git a/Chart/areachart.cpp b/Chart/areachart.cpp index 39e6e42..385ac29 100644 --- a/Chart/areachart.cpp +++ b/Chart/areachart.cpp @@ -4,10 +4,11 @@ class AreaChart::AreaChartPrivate { public: - AreaChartPrivate(ChartView *parent) - :owner(parent){ - areaSeries = new QAreaSeries(owner); - scatterSeries = new QScatterSeries(owner); + explicit AreaChartPrivate(ChartView *parent) + : q_ptr(parent) + { + areaSeries = new QAreaSeries(q_ptr); + scatterSeries = new QScatterSeries(q_ptr); scatterSeries->setMarkerSize(8); chart = new QChart; @@ -18,7 +19,9 @@ class AreaChart::AreaChartPrivate chart->axes(Qt::Horizontal).first()->setRange(0, 100); chart->axes(Qt::Vertical).first()->setRange(0, 100); } - ChartView *owner; + + ChartView *q_ptr; + QChart *chart; QAreaSeries *areaSeries; QScatterSeries *scatterSeries; @@ -31,9 +34,7 @@ AreaChart::AreaChart(QWidget *parent) setupUI(); } -AreaChart::~AreaChart() -{ -} +AreaChart::~AreaChart() = default; void AreaChart::setupUI() { @@ -44,7 +45,7 @@ void AreaChart::setupUI() QLineSeries *upperSeries = new QLineSeries(this); QLineSeries *lowerSeries = new QLineSeries(this); upperSeries->replace(pointList); - for(int i=0; ireplace(pointList); diff --git a/Chart/areachart.h b/Chart/areachart.h index f81b64b..6dfe3d7 100644 --- a/Chart/areachart.h +++ b/Chart/areachart.h @@ -7,7 +7,7 @@ class AreaChart : public ChartView { public: explicit AreaChart(QWidget *parent = nullptr); - ~AreaChart(); + ~AreaChart() override; private: void setupUI(); diff --git a/Chart/callout.cpp b/Chart/callout.cpp index bb37802..ba7cd24 100644 --- a/Chart/callout.cpp +++ b/Chart/callout.cpp @@ -28,19 +28,18 @@ ****************************************************************************/ #include "callout.h" -#include +#include #include -#include #include -#include +#include +#include -Callout::Callout(QChart *chart): - QGraphicsItem(chart), - m_chart(chart) -{ -} +Callout::Callout(QChart *chart) + : QGraphicsItem(chart) + , m_chart(chart) +{} -QRectF Callout::boundingRect() const +auto Callout::boundingRect() const -> QRectF { QPointF anchor = mapFromParent(m_chart->mapToPosition(m_anchor)); QRectF rect; @@ -76,16 +75,24 @@ void Callout::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, Q // get the nearest m_rect corner. qreal x = (onRight + rightOfCenter) * m_rect.width(); qreal y = (below + belowCenter) * m_rect.height(); - bool cornerCase = (above && onLeft) || (above && onRight) || (below && onLeft) || (below && onRight); + bool cornerCase = (above && onLeft) || (above && onRight) || (below && onLeft) + || (below && onRight); bool vertical = qAbs(anchor.x() - x) > qAbs(anchor.y() - y); - qreal x1 = x + leftOfCenter * 10 - rightOfCenter * 20 + cornerCase * !vertical * (onLeft * 10 - onRight * 20); - qreal y1 = y + aboveCenter * 10 - belowCenter * 20 + cornerCase * vertical * (above * 10 - below * 20);; + qreal x1 = x + leftOfCenter * 10 - rightOfCenter * 20 + + cornerCase * !vertical * (onLeft * 10 - onRight * 20); + qreal y1 = y + aboveCenter * 10 - belowCenter * 20 + + cornerCase * vertical * (above * 10 - below * 20); + ; point1.setX(x1); point1.setY(y1); - qreal x2 = x + leftOfCenter * 20 - rightOfCenter * 10 + cornerCase * !vertical * (onLeft * 20 - onRight * 10);; - qreal y2 = y + aboveCenter * 20 - belowCenter * 10 + cornerCase * vertical * (above * 20 - below * 10);; + qreal x2 = x + leftOfCenter * 20 - rightOfCenter * 10 + + cornerCase * !vertical * (onLeft * 20 - onRight * 10); + ; + qreal y2 = y + aboveCenter * 20 - belowCenter * 10 + + cornerCase * vertical * (above * 20 - below * 10); + ; point2.setX(x2); point2.setY(y2); @@ -106,7 +113,7 @@ void Callout::mousePressEvent(QGraphicsSceneMouseEvent *event) void Callout::mouseMoveEvent(QGraphicsSceneMouseEvent *event) { - if (event->buttons() & Qt::LeftButton){ + if (event->buttons() & Qt::LeftButton) { setPos(mapToParent(event->pos() - event->buttonDownPos(Qt::LeftButton))); event->setAccepted(true); } else { diff --git a/Chart/callout.h b/Chart/callout.h index ddc444d..39c0fae 100644 --- a/Chart/callout.h +++ b/Chart/callout.h @@ -31,8 +31,8 @@ #define CALLOUT_H #include -#include #include +#include QT_BEGIN_NAMESPACE class QGraphicsSceneMouseEvent; @@ -49,12 +49,12 @@ class Callout : public QGraphicsItem void setAnchor(QPointF point); void updateGeometry(); - QRectF boundingRect() const; - void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,QWidget *widget); + [[nodiscard]] auto boundingRect() const -> QRectF override; + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override; protected: - void mousePressEvent(QGraphicsSceneMouseEvent *event); - void mouseMoveEvent(QGraphicsSceneMouseEvent *event); + void mousePressEvent(QGraphicsSceneMouseEvent *event) override; + void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override; private: QString m_text; diff --git a/Chart/chartlabel.cpp b/Chart/chartlabel.cpp deleted file mode 100644 index 182c3fb..0000000 --- a/Chart/chartlabel.cpp +++ /dev/null @@ -1,7 +0,0 @@ -#include "chartlabel.h" - -ChartLabel::ChartLabel(QChart *parent) - : QGraphicsItem(parent) -{ - -} diff --git a/Chart/chartlabel.h b/Chart/chartlabel.h deleted file mode 100644 index b35929e..0000000 --- a/Chart/chartlabel.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef CHARTLABEL_H -#define CHARTLABEL_H - -#include - -class ChartLabel : public QGraphicsItem -{ -public: - explicit ChartLabel(QChart *parent); -}; - -#endif // CHARTLABEL_H diff --git a/Chart/chartview.cpp b/Chart/chartview.cpp index db67de8..4c0b4d5 100644 --- a/Chart/chartview.cpp +++ b/Chart/chartview.cpp @@ -1,33 +1,18 @@ #include "chartview.h" ChartView::ChartView(QWidget *parent) - :QChartView(parent) -{ -} + : QChartView(parent) +{} void ChartView::keyPressEvent(QKeyEvent *event) { switch (event->key()) { - case Qt::Key_Plus: - chart()->zoomIn(); - break; - case Qt::Key_Minus: - chart()->zoomOut(); - break; - case Qt::Key_Left: - chart()->scroll(-1.0, 0); - break; - case Qt::Key_Right: - chart()->scroll(1.0, 0); - break; - case Qt::Key_Up: - chart()->scroll(0, 1.0); - break; - case Qt::Key_Down: - chart()->scroll(0, -1.0); - break; - default: - QGraphicsView::keyPressEvent(event); - break; + case Qt::Key_Plus: chart()->zoomIn(); break; + case Qt::Key_Minus: chart()->zoomOut(); break; + case Qt::Key_Left: chart()->scroll(-1.0, 0); break; + case Qt::Key_Right: chart()->scroll(1.0, 0); break; + case Qt::Key_Up: chart()->scroll(0, 1.0); break; + case Qt::Key_Down: chart()->scroll(0, -1.0); break; + default: QGraphicsView::keyPressEvent(event); break; } } diff --git a/Chart/datetimechart.cpp b/Chart/datetimechart.cpp index 54a5b29..c5def72 100644 --- a/Chart/datetimechart.cpp +++ b/Chart/datetimechart.cpp @@ -4,19 +4,19 @@ class DateTimeChart::DateTimeChartPrivate { public: - DateTimeChartPrivate(ChartView *parent) - : owner(parent) + explicit DateTimeChartPrivate(ChartView *parent) + : q_ptr(parent) { - dateTimeAxisX = new QDateTimeAxis(owner); + dateTimeAxisX = new QDateTimeAxis(q_ptr); dateTimeAxisX->setFormat("yyyy-MM"); //dateTimeAxisX->setTitleText(QObject::tr("Date")); - valueAxisY = new QValueAxis(owner); + valueAxisY = new QValueAxis(q_ptr); //valueAxisY->setTitleText(QObject::tr("Value")); valueAxisY->setRange(0, 100); - lineSeries = new QLineSeries(owner); - scatterSeries = new QScatterSeries(owner); + lineSeries = new QLineSeries(q_ptr); + scatterSeries = new QScatterSeries(q_ptr); scatterSeries->setMarkerSize(8); PointList pointList = generateRandomDataPoints(5, 101); @@ -42,7 +42,9 @@ class DateTimeChart::DateTimeChartPrivate scatterSeries->attachAxis(dateTimeAxisX); scatterSeries->attachAxis(valueAxisY); } - ChartView *owner; + + ChartView *q_ptr; + QChart *chart; QDateTimeAxis *dateTimeAxisX; QValueAxis *valueAxisY; @@ -57,9 +59,7 @@ DateTimeChart::DateTimeChart(QWidget *parent) setupUI(); } -DateTimeChart::~DateTimeChart() -{ -} +DateTimeChart::~DateTimeChart() = default; void DateTimeChart::setupUI() { diff --git a/Chart/datetimechart.h b/Chart/datetimechart.h index 9007a5a..84b857a 100644 --- a/Chart/datetimechart.h +++ b/Chart/datetimechart.h @@ -7,7 +7,7 @@ class DateTimeChart : public ChartView { public: explicit DateTimeChart(QWidget *parent = nullptr); - ~DateTimeChart(); + ~DateTimeChart() override; private: void setupUI(); diff --git a/Chart/dialogchart.cpp b/Chart/dialogchart.cpp index f576bc5..1723fdc 100644 --- a/Chart/dialogchart.cpp +++ b/Chart/dialogchart.cpp @@ -3,14 +3,14 @@ #include DialogChart::DialogChart(QGraphicsScene *scene, QWidget *parent) - :QDialog(parent) - ,m_scene(scene) + : QDialog(parent) + , m_scene(scene) { - view = new QChartView; - view->setRenderHint(QPainter::Antialiasing); - view->setScene(scene); + m_view = new QChartView; + m_view->setRenderHint(QPainter::Antialiasing); + m_view->setScene(scene); QHBoxLayout *layout = new QHBoxLayout(this); - layout->addWidget(view); + layout->addWidget(m_view); } void DialogChart::resizeEvent(QResizeEvent *event) @@ -18,8 +18,8 @@ void DialogChart::resizeEvent(QResizeEvent *event) qreal sx = event->size().width() / m_scene->width(); qreal sy = event->size().height() / m_scene->height(); qreal min = qMin(sx, sy); - view->scale(min, min); - view->show(); + m_view->scale(min, min); + m_view->show(); qDebug() << min; QDialog::resizeEvent(event); diff --git a/Chart/dialogchart.h b/Chart/dialogchart.h index a374622..237a322 100644 --- a/Chart/dialogchart.h +++ b/Chart/dialogchart.h @@ -13,7 +13,7 @@ class DialogChart : public QDialog void resizeEvent(QResizeEvent *) override; private: - QChartView *view; + QChartView *m_view; QGraphicsScene *m_scene; }; diff --git a/Chart/dynamicchart.cpp b/Chart/dynamicchart.cpp index 1accabe..f1d7303 100644 --- a/Chart/dynamicchart.cpp +++ b/Chart/dynamicchart.cpp @@ -3,9 +3,8 @@ class DynamicChart::DynamicChartPrivate { public: - DynamicChartPrivate(ChartView *parent) + explicit DynamicChartPrivate(ChartView *parent) : owner(parent) - , timerId(0) { splineSeries = new QSplineSeries(owner); scatterSeries = new QScatterSeries(owner); @@ -24,7 +23,7 @@ class DynamicChart::DynamicChartPrivate QChart *chart; QSplineSeries *splineSeries; QScatterSeries *scatterSeries; - int timerId; + int timerId = 0; QList data; }; @@ -36,9 +35,7 @@ DynamicChart::DynamicChart(QWidget *parent) startChart(); } -DynamicChart::~DynamicChart() -{ -} +DynamicChart::~DynamicChart() = default; void DynamicChart::timerEvent(QTimerEvent *event) { @@ -56,8 +53,9 @@ void DynamicChart::dataReceived(int value) d_ptr->data.removeFirst(); } - if (!isVisible()) + if (!isVisible()) { return; + } d_ptr->splineSeries->clear(); d_ptr->scatterSeries->clear(); diff --git a/Chart/dynamicchartx.cpp b/Chart/dynamicchartx.cpp index 8c4c968..2f8f886 100644 --- a/Chart/dynamicchartx.cpp +++ b/Chart/dynamicchartx.cpp @@ -1,15 +1,14 @@ #include "dynamicchartx.h" -class DynamicChartXPrivate{ +class DynamicChartX::DynamicChartXPrivate +{ public: - DynamicChartXPrivate(ChartView *parent) - : owner(parent) - , timerId(0) - , xValue(0) + explicit DynamicChartXPrivate(ChartView *parent) + : q_ptr(parent) { - valueAxis = new QValueAxis(owner); - splineSeries = new QSplineSeries(owner); - scatterSeries = new QScatterSeries(owner); + valueAxis = new QValueAxis(q_ptr); + splineSeries = new QSplineSeries(q_ptr); + scatterSeries = new QScatterSeries(q_ptr); scatterSeries->setMarkerSize(8); chart = new QChart; @@ -25,32 +24,30 @@ class DynamicChartXPrivate{ chart->axes(Qt::Vertical).first()->setRange(0, 100); } - ChartView *owner; + ChartView *q_ptr; + QChart *chart; QValueAxis *valueAxis; QSplineSeries *splineSeries; QScatterSeries *scatterSeries; - int timerId; + int timerId = 0; QList data; - qreal xValue; + qreal xValue = 0; }; DynamicChartX::DynamicChartX(QWidget *parent) : ChartView(parent) - , d(new DynamicChartXPrivate(this)) + , d_ptr(new DynamicChartXPrivate(this)) { setupChart(); startChart(); } -DynamicChartX::~DynamicChartX() -{ - delete d; -} +DynamicChartX::~DynamicChartX() = default; void DynamicChartX::timerEvent(QTimerEvent *event) { - if (event->timerId() == d->timerId) { + if (event->timerId() == d_ptr->timerId) { int newData = QRandomGenerator::global()->generate() % (100 + 1); dataReceived(newData); } @@ -58,29 +55,30 @@ void DynamicChartX::timerEvent(QTimerEvent *event) void DynamicChartX::dataReceived(int value) { - if(!isVisible()) + if (!isVisible()) { return; - qreal x = d->chart->plotArea().width() / 10; - d->splineSeries->append(d->xValue*100/10, value); - d->scatterSeries->append(d->xValue*100/10, value); - if(d->xValue > 10) - d->chart->scroll(x, 0); - d->xValue++; - if(d->splineSeries->points().size() > 10) - { - d->splineSeries->points().removeFirst(); - d->scatterSeries->points().removeFirst(); + } + qreal x = d_ptr->chart->plotArea().width() / 10; + d_ptr->splineSeries->append(d_ptr->xValue * 100 / 10, value); + d_ptr->scatterSeries->append(d_ptr->xValue * 100 / 10, value); + if (d_ptr->xValue > 10) { + d_ptr->chart->scroll(x, 0); + } + d_ptr->xValue++; + if (d_ptr->splineSeries->points().size() > 10) { + d_ptr->splineSeries->points().removeFirst(); + d_ptr->scatterSeries->points().removeFirst(); } } void DynamicChartX::startChart() { - d->timerId = startTimer(1000); + d_ptr->timerId = startTimer(1000); //QRandomGenerator::global()->seed(QDateTime::currentSecsSinceEpoch()); } void DynamicChartX::setupChart() { setRenderHint(QPainter::Antialiasing); - setChart(d->chart); + setChart(d_ptr->chart); } diff --git a/Chart/dynamicchartx.h b/Chart/dynamicchartx.h index 95cb911..74396e1 100644 --- a/Chart/dynamicchartx.h +++ b/Chart/dynamicchartx.h @@ -3,11 +3,10 @@ #include "chartview.h" -class DynamicChartXPrivate; class DynamicChartX : public ChartView { public: - DynamicChartX(QWidget *parent = nullptr); + explicit DynamicChartX(QWidget *parent = nullptr); ~DynamicChartX() override; protected: @@ -17,7 +16,9 @@ class DynamicChartX : public ChartView void dataReceived(int value); void startChart(); void setupChart(); - DynamicChartXPrivate *d; + + class DynamicChartXPrivate; + QScopedPointer d_ptr; }; #endif // DYNAMICCHARTX_H diff --git a/Chart/linechart.cpp b/Chart/linechart.cpp index e66574b..b863255 100644 --- a/Chart/linechart.cpp +++ b/Chart/linechart.cpp @@ -3,12 +3,14 @@ #include "callout.h" #include "dialogchart.h" -class LineChartPrivate{ +class LineChart::LineChartPrivate +{ public: - LineChartPrivate(ChartView *parent) - :owner(parent){ - lineSeries = new QLineSeries(owner); - scatterSeries = new QScatterSeries(owner); + explicit LineChartPrivate(ChartView *parent) + : q_ptr(parent) + { + lineSeries = new QLineSeries(q_ptr); + scatterSeries = new QScatterSeries(q_ptr); scatterSeries->setMarkerSize(8); chart = new QChart; @@ -29,11 +31,13 @@ class LineChartPrivate{ xValue->setText(QObject::tr("X: ")); yValue->setText(QObject::tr("Y: ")); - button = new QPushButton(QObject::tr("Eject"), owner); + button = new QPushButton(QObject::tr("Eject"), q_ptr); button->move(5, 5); button->setFlat(true); } - ChartView *owner; + + ChartView *q_ptr; + QChart *chart; QLineSeries *lineSeries; QScatterSeries *scatterSeries; @@ -48,33 +52,31 @@ class LineChartPrivate{ }; LineChart::LineChart(QWidget *parent) - :ChartView(parent) - ,d(new LineChartPrivate(this)) + : ChartView(parent) + , d_ptr(new LineChartPrivate(this)) { setupUI(); buildConnect(); } -LineChart::~LineChart() -{ - delete d; -} +LineChart::~LineChart() = default; void LineChart::resizeEvent(QResizeEvent *event) { //d->chart->resize(event->size()); - d->xValue->setPos(d->chart->size().width() - 170, 10); - d->yValue->setPos(d->chart->size().width() - 85, 10); - const auto callouts = d->toolTipList; - for (Callout *callout : callouts) + d_ptr->xValue->setPos(d_ptr->chart->size().width() - 170, 10); + d_ptr->yValue->setPos(d_ptr->chart->size().width() - 85, 10); + const auto callouts = d_ptr->toolTipList; + for (Callout *callout : callouts) { callout->updateGeometry(); + } QChartView::resizeEvent(event); } void LineChart::mouseMoveEvent(QMouseEvent *event) { - d->xValue->setText(QObject::tr("X: %1").arg(d->chart->mapToValue(event->pos()).x())); - d->yValue->setText(QObject::tr("Y: %1").arg(d->chart->mapToValue(event->pos()).x())); + d_ptr->xValue->setText(QObject::tr("X: %1").arg(d_ptr->chart->mapToValue(event->pos()).x())); + d_ptr->yValue->setText(QObject::tr("Y: %1").arg(d_ptr->chart->mapToValue(event->pos()).x())); QChartView::mouseMoveEvent(event); } @@ -82,42 +84,43 @@ void LineChart::wheelEvent(QWheelEvent *event) { int nd = event->angleDelta().rx() / 8; double scale =1.0 / pow(0.9, nd / 15.0f); - d->chart->zoom(scale); + d_ptr->chart->zoom(scale); update(); QChartView::wheelEvent(event); } void LineChart::keepToolTip() { - d->toolTipList.append(d->toolTip); - d->toolTip = new Callout(d->chart); + d_ptr->toolTipList.append(d_ptr->toolTip); + d_ptr->toolTip = new Callout(d_ptr->chart); } void LineChart::toolTip(QPointF point, bool state) { - if (d->toolTip == nullptr) - d->toolTip = new Callout(d->chart); + if (d_ptr->toolTip == nullptr) { + d_ptr->toolTip = new Callout(d_ptr->chart); + } if (state) { - d->toolTip->setText(QString(tr("X: %1 \nY: %2 ")).arg(point.x()).arg(point.y())); - d->toolTip->setAnchor(point); - d->toolTip->setZValue(11); - d->toolTip->updateGeometry(); - d->toolTip->show(); + d_ptr->toolTip->setText(QString(tr("X: %1 \nY: %2 ")).arg(point.x()).arg(point.y())); + d_ptr->toolTip->setAnchor(point); + d_ptr->toolTip->setZValue(11); + d_ptr->toolTip->updateGeometry(); + d_ptr->toolTip->show(); } else { - d->toolTip->hide(); + d_ptr->toolTip->hide(); } } void LineChart::showDialog() { hide(); - DialogChart *dialog = new DialogChart(d->chart->scene(), this); + DialogChart *dialog = new DialogChart(d_ptr->chart->scene(), this); dialog->resize(640, 480); dialog->exec(); delete dialog; dialog = nullptr; - setChart(d->chart); + setChart(d_ptr->chart); show(); } @@ -125,16 +128,16 @@ void LineChart::setupUI() { setMouseTracking(true); setRenderHint(QPainter::Antialiasing); - setChart(d->chart); + setChart(d_ptr->chart); PointList pointList = generateRandomDataPoints(5, 101); - d->lineSeries->replace(pointList); - d->scatterSeries->replace(pointList); + d_ptr->lineSeries->replace(pointList); + d_ptr->scatterSeries->replace(pointList); } void LineChart::buildConnect() { - connect(d->scatterSeries, &QScatterSeries::clicked, this, &LineChart::keepToolTip); - connect(d->scatterSeries, &QScatterSeries::hovered, this, &LineChart::toolTip); + connect(d_ptr->scatterSeries, &QScatterSeries::clicked, this, &LineChart::keepToolTip); + connect(d_ptr->scatterSeries, &QScatterSeries::hovered, this, &LineChart::toolTip); - connect(d->button, &QPushButton::clicked, this, &LineChart::showDialog); + connect(d_ptr->button, &QPushButton::clicked, this, &LineChart::showDialog); } diff --git a/Chart/linechart.h b/Chart/linechart.h index a01be21..db8ab15 100644 --- a/Chart/linechart.h +++ b/Chart/linechart.h @@ -3,12 +3,11 @@ #include "chartview.h" -class LineChartPrivate; class LineChart : public ChartView { Q_OBJECT public: - LineChart(QWidget *parent = nullptr); + explicit LineChart(QWidget *parent = nullptr); ~LineChart() override; protected: @@ -25,7 +24,9 @@ private slots: private: void setupUI(); void buildConnect(); - LineChartPrivate *d; + + class LineChartPrivate; + QScopedPointer d_ptr; }; #endif // LINECHART_H diff --git a/Chart/main.cpp b/Chart/main.cpp index fd3e533..24ba3b6 100644 --- a/Chart/main.cpp +++ b/Chart/main.cpp @@ -2,7 +2,7 @@ #include -int main(int argc, char *argv[]) +auto main(int argc, char *argv[]) -> int { QApplication a(argc, argv); MainWindow w; diff --git a/Chart/mainwindow.cpp b/Chart/mainwindow.cpp index d14ef28..a92df2c 100644 --- a/Chart/mainwindow.cpp +++ b/Chart/mainwindow.cpp @@ -1,11 +1,11 @@ #include "mainwindow.h" +#include "areachart.h" +#include "datetimechart.h" #include "dynamicchart.h" #include "dynamicchartx.h" -#include "areachart.h" #include "linechart.h" -#include "stackedbarchart.h" #include "piechart.h" -#include "datetimechart.h" +#include "stackedbarchart.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) @@ -13,9 +13,7 @@ MainWindow::MainWindow(QWidget *parent) setupUI(); } -MainWindow::~MainWindow() -{ -} +MainWindow::~MainWindow() {} void MainWindow::setupUI() { @@ -33,4 +31,3 @@ void MainWindow::setupUI() setCentralWidget(frame); setMinimumSize(960, 600); } - diff --git a/Chart/mainwindow.h b/Chart/mainwindow.h index 249c63a..ad3198a 100644 --- a/Chart/mainwindow.h +++ b/Chart/mainwindow.h @@ -6,10 +6,9 @@ class MainWindow : public QMainWindow { Q_OBJECT - public: - MainWindow(QWidget *parent = nullptr); - ~MainWindow(); + explicit MainWindow(QWidget *parent = nullptr); + ~MainWindow() override; private: void setupUI(); diff --git a/Chart/normalchartdata.cpp b/Chart/normalchartdata.cpp index d7f9488..8be4713 100644 --- a/Chart/normalchartdata.cpp +++ b/Chart/normalchartdata.cpp @@ -1,10 +1,13 @@ #include "normalchartdata.h" -PointList generateRandomDataPoints(int listCount, int valueMax){ +#include + +auto generateRandomDataPoints(int listCount, int valueMax) -> PointList +{ PointList pointList; qreal yValue(0); int count = valueMax / listCount; - for(int i=0; ibounded(valueMax / qreal(listCount)); QPointF pointF(i, yValue); pointList.append(pointF); diff --git a/Chart/normalchartdata.h b/Chart/normalchartdata.h index f489ad2..e02e8f2 100644 --- a/Chart/normalchartdata.h +++ b/Chart/normalchartdata.h @@ -1,12 +1,11 @@ #ifndef NORMALCHARTDATA_H #define NORMALCHARTDATA_H -#include #include -#include +#include -typedef QList PointList; +using PointList = QList; -PointList generateRandomDataPoints(int listCount, int valueMax); +auto generateRandomDataPoints(int listCount, int valueMax) -> PointList; #endif // NORMALCHARTDATA_H diff --git a/Chart/piechart.cpp b/Chart/piechart.cpp index 4e1847f..68836c5 100644 --- a/Chart/piechart.cpp +++ b/Chart/piechart.cpp @@ -1,40 +1,41 @@ #include "piechart.h" #include "normalchartdata.h" -class PieChartPrivate{ +class PieChart::PieChartPrivate +{ public: - PieChartPrivate(ChartView *parent) - :owner(parent){ - pieSeries = new QPieSeries(owner); + explicit PieChartPrivate(ChartView *parent) + : q_ptr(parent) + { + pieSeries = new QPieSeries(q_ptr); chart = new QChart; chart->setAnimationOptions(QChart::AllAnimations); chart->setTitle(QObject::tr("Pie Chart")); } - ChartView *owner; + + ChartView *q_ptr; + QChart *chart; QPieSeries *pieSeries; }; PieChart::PieChart(QWidget *parent) - :ChartView(parent) - ,d(new PieChartPrivate(this)) + : ChartView(parent) + , d_ptr(new PieChartPrivate(this)) { setupUI(); } -PieChart::~PieChart() -{ - delete d; -} +PieChart::~PieChart() = default; void PieChart::setupUI() { setRenderHint(QPainter::Antialiasing); - setChart(d->chart); + setChart(d_ptr->chart); PointList pointList = generateRandomDataPoints(5, 100); for(int i=0; ipieSeries->append(tr("P%1").arg(i), pointList[i].y()); + QPieSlice *slice = d_ptr->pieSeries->append(tr("P%1").arg(i), pointList[i].y()); if(i == 0){ // Show the first slice exploded with label slice->setLabelVisible(); @@ -43,5 +44,5 @@ void PieChart::setupUI() } } - d->chart->addSeries(d->pieSeries); + d_ptr->chart->addSeries(d_ptr->pieSeries); } diff --git a/Chart/piechart.h b/Chart/piechart.h index 38d62b7..ba7e74a 100644 --- a/Chart/piechart.h +++ b/Chart/piechart.h @@ -3,16 +3,17 @@ #include "chartview.h" -class PieChartPrivate; class PieChart : public ChartView { public: - PieChart(QWidget *parent = nullptr); - ~PieChart(); + explicit PieChart(QWidget *parent = nullptr); + ~PieChart() override; private: void setupUI(); - PieChartPrivate *d; + + class PieChartPrivate; + QScopedPointer d_ptr; }; #endif // PIECHART_H diff --git a/Chart/stackedbarchart.cpp b/Chart/stackedbarchart.cpp index 7bdafd8..9f7bb2d 100644 --- a/Chart/stackedbarchart.cpp +++ b/Chart/stackedbarchart.cpp @@ -1,13 +1,15 @@ #include "stackedbarchart.h" #include "normalchartdata.h" -class StackedBarChartPrivate{ +class StackedBarChart::StackedBarChartPrivate +{ public: - StackedBarChartPrivate(ChartView *parent) - :owner(parent){ - stackedBarSeries = new QStackedBarSeries(owner); + explicit StackedBarChartPrivate(ChartView *parent) + : q_ptr(parent) + { + stackedBarSeries = new QStackedBarSeries(q_ptr); PointList pointList = generateRandomDataPoints(5, 101); - QBarSet *set = new QBarSet("Bar set", owner); + QBarSet *set = new QBarSet("Bar set", q_ptr); foreach(const QPointF& p, pointList) *set << p.y(); stackedBarSeries->append(set); // 先添加点集,不然x轴为空 @@ -20,24 +22,23 @@ class StackedBarChartPrivate{ chart->axes(Qt::Horizontal).first()->setRange(0, 100); chart->axes(Qt::Vertical).first()->setRange(0, 100); } - ChartView *owner; + + ChartView *q_ptr; + QChart *chart; QStackedBarSeries *stackedBarSeries; }; StackedBarChart::StackedBarChart(QWidget *parent) - :ChartView(parent) - ,d(new StackedBarChartPrivate(this)) + : ChartView(parent) + , d_ptr(new StackedBarChartPrivate(this)) { setupUI(); } -StackedBarChart::~StackedBarChart() -{ - delete d; -} +StackedBarChart::~StackedBarChart() = default; void StackedBarChart::setupUI() { - setChart(d->chart); + setChart(d_ptr->chart); } diff --git a/Chart/stackedbarchart.h b/Chart/stackedbarchart.h index ed01d07..56ef6cc 100644 --- a/Chart/stackedbarchart.h +++ b/Chart/stackedbarchart.h @@ -3,16 +3,17 @@ #include "chartview.h" -class StackedBarChartPrivate; class StackedBarChart : public ChartView { public: - StackedBarChart(QWidget *parent = nullptr); - ~StackedBarChart(); + explicit StackedBarChart(QWidget *parent = nullptr); + ~StackedBarChart() override; private: void setupUI(); - StackedBarChartPrivate *d; + + class StackedBarChartPrivate; + QScopedPointer d_ptr; }; #endif // STACKEDBARCHART_H diff --git a/CheckBoxStandardItem/main.cc b/CheckBoxStandardItem/main.cc index e9bbf59..5d48a9d 100644 --- a/CheckBoxStandardItem/main.cc +++ b/CheckBoxStandardItem/main.cc @@ -7,7 +7,7 @@ #include #endif -int main(int argc, char *argv[]) +auto main(int argc, char *argv[]) -> int { QApplication a(argc, argv); MainWindow w; diff --git a/CheckBoxStandardItem/mainwindow.hpp b/CheckBoxStandardItem/mainwindow.hpp index 2a84cf2..2cabee1 100644 --- a/CheckBoxStandardItem/mainwindow.hpp +++ b/CheckBoxStandardItem/mainwindow.hpp @@ -1,19 +1,13 @@ #ifndef MAINWINDOW_HPP #define MAINWINDOW_HPP -#include -#if QT_VERSION >= 0x050000 -#include -#else -#include -#endif +#include class MainWindow : public QMainWindow { Q_OBJECT - - public: - MainWindow(QWidget *parent = nullptr); - ~MainWindow(); +public: + explicit MainWindow(QWidget *parent = nullptr); + ~MainWindow() override; }; #endif // MAINWINDOW_HPP diff --git a/Clock/clockwidget.cpp b/Clock/clockwidget.cpp index 466e72d..3b80fed 100644 --- a/Clock/clockwidget.cpp +++ b/Clock/clockwidget.cpp @@ -1,23 +1,27 @@ #include "clockwidget.h" +#include #include -#include -#include #include +#include #include -#include +#include -class ClockWidgetPrivate{ +class ClockWidget::ClockWidgetPrivate +{ public: - ClockWidgetPrivate(QWidget *parent) - : owner(parent){ + explicit ClockWidgetPrivate(QWidget *parent) + : q_ptr(parent) + { QTime time = QTime::currentTime(); hour = time.hour(); minute = time.minute(); second = time.minute(); microSecond = time.msec(); } - QWidget *owner; + + QWidget *q_ptr; + QColor borderColor = QColor(254, 254, 254); QColor backgroundColor = QColor(80, 80, 80); QColor foregroundColor = QColor(254, 254, 254); @@ -33,91 +37,89 @@ class ClockWidgetPrivate{ ClockWidget::ClockWidget(QWidget *parent) : QWidget(parent) - , d(new ClockWidgetPrivate(this)) + , d_ptr(new ClockWidgetPrivate(this)) { setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - connect(&d->timer, &QTimer::timeout, this, &ClockWidget::setOffset); - d->timer.start(1000); + connect(&d_ptr->timer, &QTimer::timeout, this, &ClockWidget::setOffset); + d_ptr->timer.start(1000); } -ClockWidget::~ClockWidget() -{ -} +ClockWidget::~ClockWidget() = default; void ClockWidget::setBorderColor(const QColor &color) { - d->borderColor = color; + d_ptr->borderColor = color; update(); } -QColor ClockWidget::borderColor() const +auto ClockWidget::borderColor() const -> QColor { - return d->borderColor; + return d_ptr->borderColor; } void ClockWidget::setBackgroundColor(const QColor &color) { - d->backgroundColor = color; + d_ptr->backgroundColor = color; update(); } -QColor ClockWidget::backgroundColor() const +auto ClockWidget::backgroundColor() const -> QColor { - return d->backgroundColor; + return d_ptr->backgroundColor; } void ClockWidget::setForegroundColor(const QColor &color) { - d->foregroundColor = color; + d_ptr->foregroundColor = color; update(); } -QColor ClockWidget::foregroundColor() const +auto ClockWidget::foregroundColor() const -> QColor { - return d->foregroundColor; + return d_ptr->foregroundColor; } void ClockWidget::setHourColor(const QColor &color) { - d->hourColor = color; + d_ptr->hourColor = color; update(); } -QColor ClockWidget::hourColor() const +auto ClockWidget::hourColor() const -> QColor { - return d->hourColor; + return d_ptr->hourColor; } void ClockWidget::setMinuteColor(const QColor &color) { - d->minuteColor = color; + d_ptr->minuteColor = color; update(); } -QColor ClockWidget::minuteColor() const +auto ClockWidget::minuteColor() const -> QColor { - return d->minuteColor; + return d_ptr->minuteColor; } void ClockWidget::setSecondColor(const QColor &color) { - d->secondColor = color; + d_ptr->secondColor = color; update(); } -QColor ClockWidget::secondColor() const +auto ClockWidget::secondColor() const -> QColor { - return d->secondColor; + return d_ptr->secondColor; } -QSize ClockWidget::sizeHint() const +auto ClockWidget::sizeHint() const -> QSize { - return QSize(500, 500); + return {500, 500}; } -QSize ClockWidget::minimumSizeHint() const +auto ClockWidget::minimumSizeHint() const -> QSize { - return QSize(300, 300); + return {300, 300}; } void ClockWidget::paintEvent(QPaintEvent *event) @@ -149,10 +151,10 @@ void ClockWidget::paintEvent(QPaintEvent *event) void ClockWidget::setOffset() { QTime time = QTime::currentTime(); - d->hour = time.hour(); - d->minute = time.minute(); - d->second = time.second(); - d->microSecond = time.msec(); + d_ptr->hour = time.hour(); + d_ptr->minute = time.minute(); + d_ptr->second = time.second(); + d_ptr->microSecond = time.msec(); update(); } @@ -161,7 +163,7 @@ void ClockWidget::drawBorder(QPainter *painter) double min = qMin(width(), height()); double radius = min / 2.0 - min / 10.0; painter->setPen(Qt::NoPen); - painter->setBrush(d->borderColor); + painter->setBrush(d_ptr->borderColor); painter->drawEllipse(-radius, -radius, radius * 2, radius * 2); } @@ -171,7 +173,7 @@ void ClockWidget::drawBackground(QPainter *painter) double radius = min / 2.0 - min / 9.0; painter->save(); painter->setPen(Qt::NoPen); - painter->setBrush(d->backgroundColor); + painter->setBrush(d_ptr->backgroundColor); painter->drawEllipse(-radius, -radius, radius * 2, radius * 2); painter->restore(); } @@ -181,7 +183,7 @@ void ClockWidget::drawScale(QPainter *painter, const double linew) painter->save(); double min = qMin(width(), height()); double radius = min / 2 - min / 8; - QPen pen(d->foregroundColor); + QPen pen(d_ptr->foregroundColor); pen.setCapStyle(Qt::RoundCap); for (int i = 0; i <= 60; i++) { @@ -203,7 +205,7 @@ void ClockWidget::drawScaleNum(QPainter *painter) { double min = qMin(width(), height()); double radius = min / 2.0 - min / 4.8; - painter->setPen(d->foregroundColor); + painter->setPen(d_ptr->foregroundColor); QFont font("Microsoft YaHei", min / 20); painter->setFont(font); @@ -229,14 +231,13 @@ void ClockWidget::drawHour(QPainter *painter) painter->save(); QPen pen; pen.setCapStyle(Qt::RoundCap); - painter->setPen(d->hourColor); - painter->setBrush(d->hourColor); + painter->setPen(d_ptr->hourColor); + painter->setBrush(d_ptr->hourColor); double min = qMin(width(), height()) / 6.0; QPolygonF pts; - pts << QPointF(-3, 8) << QPointF(3, 8) - << QPointF(2, -min) << QPointF(-2, -min); - painter->rotate(30.0 * ((d->hour + d->minute / 60.0))); + pts << QPointF(-3, 8) << QPointF(3, 8) << QPointF(2, -min) << QPointF(-2, -min); + painter->rotate(30.0 * ((d_ptr->hour + d_ptr->minute / 60.0))); painter->drawConvexPolygon(pts); painter->restore(); } @@ -246,14 +247,13 @@ void ClockWidget::drawMinute(QPainter *painter) painter->save(); QPen pen; pen.setCapStyle(Qt::RoundCap); - painter->setPen(d->minuteColor); - painter->setBrush(d->minuteColor); + painter->setPen(d_ptr->minuteColor); + painter->setBrush(d_ptr->minuteColor); double min = qMin(width(), height()) / 5.0; QPolygonF pts; - pts << QPointF(-2, 8) << QPointF(2, 8) - << QPointF(1, -min) << QPointF(-1, -min); - painter->rotate(6.0 * (d->minute + d->second / 60.0)); + pts << QPointF(-2, 8) << QPointF(2, 8) << QPointF(1, -min) << QPointF(-1, -min); + painter->rotate(6.0 * (d_ptr->minute + d_ptr->second / 60.0)); painter->drawConvexPolygon(pts); painter->restore(); } @@ -263,13 +263,13 @@ void ClockWidget::drawSecond(QPainter *painter) painter->save(); QPen pen; pen.setCapStyle(Qt::RoundCap); - painter->setPen(d->secondColor); - painter->setBrush(d->secondColor); + painter->setPen(d_ptr->secondColor); + painter->setBrush(d_ptr->secondColor); double min = qMin(width(), height()) / 4.0; QPolygonF pts; pts << QPointF(-1, 10) << QPointF(1, 10) << QPointF(0, -min); - painter->rotate(6.0 * (d->second + d->microSecond / 1000.0)); + painter->rotate(6.0 * (d_ptr->second + d_ptr->microSecond / 1000.0)); painter->drawConvexPolygon(pts); painter->restore(); } @@ -278,14 +278,12 @@ void ClockWidget::drawDot(QPainter *painter) { painter->save(); QConicalGradient coneGradient(0, 0, -90.0); - coneGradient.setColorAt(0.0, d->backgroundColor); - coneGradient.setColorAt(0.5, d->foregroundColor); - coneGradient.setColorAt(1.0, d->backgroundColor); + coneGradient.setColorAt(0.0, d_ptr->backgroundColor); + coneGradient.setColorAt(0.5, d_ptr->foregroundColor); + coneGradient.setColorAt(1.0, d_ptr->backgroundColor); painter->setOpacity(0.9); painter->setPen(Qt::NoPen); painter->setBrush(coneGradient); painter->drawEllipse(-5, -5, 10, 10); painter->restore(); } - - diff --git a/Clock/clockwidget.h b/Clock/clockwidget.h index b2c57f4..9cf3235 100644 --- a/Clock/clockwidget.h +++ b/Clock/clockwidget.h @@ -3,7 +3,6 @@ #include -class ClockWidgetPrivate; class ClockWidget : public QWidget { Q_OBJECT @@ -15,28 +14,28 @@ class ClockWidget : public QWidget Q_PROPERTY(QColor secondColor READ secondColor WRITE setSecondColor) public: explicit ClockWidget(QWidget *parent = nullptr); - ~ClockWidget(); + ~ClockWidget() override; - QSize sizeHint() const override; - QSize minimumSizeHint() const override; + [[nodiscard]] auto sizeHint() const -> QSize override; + [[nodiscard]] auto minimumSizeHint() const -> QSize override; void setBorderColor(const QColor &color); - QColor borderColor() const; + [[nodiscard]] auto borderColor() const -> QColor; void setBackgroundColor(const QColor &color); - QColor backgroundColor() const; + [[nodiscard]] auto backgroundColor() const -> QColor; void setForegroundColor(const QColor &color); - QColor foregroundColor() const; + [[nodiscard]] auto foregroundColor() const -> QColor; void setHourColor(const QColor &color); - QColor hourColor() const; + [[nodiscard]] auto hourColor() const -> QColor; void setMinuteColor(const QColor &color); - QColor minuteColor() const; + [[nodiscard]] auto minuteColor() const -> QColor; void setSecondColor(const QColor &color); - QColor secondColor() const; + [[nodiscard]] auto secondColor() const -> QColor; protected: void paintEvent(QPaintEvent *event) override; @@ -47,14 +46,15 @@ private slots: private: void drawBorder(QPainter *painter); void drawBackground(QPainter *painter); - void drawScale(QPainter *painter, const double linew); + void drawScale(QPainter *painter, double linew); void drawScaleNum(QPainter *painter); void drawHour(QPainter *painter); void drawMinute(QPainter *painter); void drawSecond(QPainter *painter); void drawDot(QPainter *painter); - QScopedPointer d; + class ClockWidgetPrivate; + QScopedPointer d_ptr; }; #endif // CLOCKWIDGET_H diff --git a/Clock/main.cpp b/Clock/main.cpp index fd3e533..24ba3b6 100644 --- a/Clock/main.cpp +++ b/Clock/main.cpp @@ -2,7 +2,7 @@ #include -int main(int argc, char *argv[]) +auto main(int argc, char *argv[]) -> int { QApplication a(argc, argv); MainWindow w; diff --git a/Clock/mainwindow.cpp b/Clock/mainwindow.cpp index 097f162..ae20f1c 100644 --- a/Clock/mainwindow.cpp +++ b/Clock/mainwindow.cpp @@ -9,7 +9,4 @@ MainWindow::MainWindow(QWidget *parent) resize(600, 480); } -MainWindow::~MainWindow() -{ -} - +MainWindow::~MainWindow() = default; diff --git a/Clock/mainwindow.h b/Clock/mainwindow.h index d147190..b50d227 100644 --- a/Clock/mainwindow.h +++ b/Clock/mainwindow.h @@ -8,7 +8,7 @@ class MainWindow : public QMainWindow Q_OBJECT public: - MainWindow(QWidget *parent = nullptr); - ~MainWindow(); + explicit MainWindow(QWidget *parent = nullptr); + ~MainWindow() override; }; #endif // MAINWINDOW_H diff --git a/DashBoard/dashboardwidget.cpp b/DashBoard/dashboardwidget.cpp index 35235d8..245febf 100644 --- a/DashBoard/dashboardwidget.cpp +++ b/DashBoard/dashboardwidget.cpp @@ -4,7 +4,8 @@ #include #include -struct DashBoardWidgetPrivate{ +struct DashBoardWidget::DashBoardWidgetPrivate +{ double maxValue = 100; double minValue = 0; double startAngle = -50; @@ -26,168 +27,166 @@ struct DashBoardWidgetPrivate{ DashBoardWidget::DashBoardWidget(QWidget *parent) : QWidget(parent) - , d(new DashBoardWidgetPrivate) + , d_ptr(new DashBoardWidgetPrivate) { - d->animation = new QPropertyAnimation(this, "value", this); + d_ptr->animation = new QPropertyAnimation(this, "value", this); setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); connect(this, &DashBoardWidget::valueChanged, this, &DashBoardWidget::onStartAnimation); } -DashBoardWidget::~DashBoardWidget() -{ -} +DashBoardWidget::~DashBoardWidget() = default; -QSize DashBoardWidget::sizeHint() const +auto DashBoardWidget::sizeHint() const -> QSize { - return QSize(300, 300); + return {300, 300}; } -QSize DashBoardWidget::minimumSizeHint() const +auto DashBoardWidget::minimumSizeHint() const -> QSize { - return QSize(200, 200); + return {200, 200}; } void DashBoardWidget::setMin(const double min) { - d->minValue = min; + d_ptr->minValue = min; update(); } -double DashBoardWidget::min() const +auto DashBoardWidget::min() const -> double { - return d->minValue; + return d_ptr->minValue; } void DashBoardWidget::setmax(const double max) { - d->maxValue = max; + d_ptr->maxValue = max; update(); } -double DashBoardWidget::max() const +auto DashBoardWidget::max() const -> double { - return d->maxValue; + return d_ptr->maxValue; } void DashBoardWidget::setStartAngle(const double startAngle) { - d->startAngle = startAngle; + d_ptr->startAngle = startAngle; update(); } -double DashBoardWidget::startAngle() const +auto DashBoardWidget::startAngle() const -> double { - return d->startAngle; + return d_ptr->startAngle; } void DashBoardWidget::setEndAngle(const double endAngle) { - d->endAngle = endAngle; + d_ptr->endAngle = endAngle; update(); } -double DashBoardWidget::endAngle() const +auto DashBoardWidget::endAngle() const -> double { - return d->endAngle; + return d_ptr->endAngle; } void DashBoardWidget::setScaleMajor(const int scale) { - d->scaleMajor = scale; + d_ptr->scaleMajor = scale; update(); } -int DashBoardWidget::scaleMajor() const +auto DashBoardWidget::scaleMajor() const -> int { - return d->scaleMajor; + return d_ptr->scaleMajor; } void DashBoardWidget::setScaleMinor(const int scale) { - d->scaleMinor = scale; + d_ptr->scaleMinor = scale; update(); } -int DashBoardWidget::scaleMinor() const +auto DashBoardWidget::scaleMinor() const -> int { - return d->scaleMinor; + return d_ptr->scaleMinor; } void DashBoardWidget::setUnit(const QString &unit) { - d->unit = unit; + d_ptr->unit = unit; update(); } -QString DashBoardWidget::unit() const +auto DashBoardWidget::unit() const -> QString { - return d->unit; + return d_ptr->unit; } void DashBoardWidget::setText(const QString &text) { - d->text = text; + d_ptr->text = text; update(); } -QString DashBoardWidget::text() const +auto DashBoardWidget::text() const -> QString { - return d->text; + return d_ptr->text; } void DashBoardWidget::setArcColor(const QColor &color) { - d->arcColor = color; + d_ptr->arcColor = color; update(); } -QColor DashBoardWidget::arcColor() const +auto DashBoardWidget::arcColor() const -> QColor { - return d->arcColor; + return d_ptr->arcColor; } void DashBoardWidget::setScaleColor(const QColor &color) { - d->scaleColor = color; + d_ptr->scaleColor = color; update(); } -QColor DashBoardWidget::scaleColor() const +auto DashBoardWidget::scaleColor() const -> QColor { - return d->scaleColor; + return d_ptr->scaleColor; } void DashBoardWidget::setPointerColor(const QColor &color) { - d->pointerColor = color; + d_ptr->pointerColor = color; update(); } -QColor DashBoardWidget::pointerColor() const +auto DashBoardWidget::pointerColor() const -> QColor { - return d->pointerColor; + return d_ptr->pointerColor; } void DashBoardWidget::setTextColor(const QColor &color) { - d->textColor = color; + d_ptr->textColor = color; update(); } -QColor DashBoardWidget::textColor() const +auto DashBoardWidget::textColor() const -> QColor { - return d->textColor; + return d_ptr->textColor; } void DashBoardWidget::setBackgroundColor(const QColor &color) { - d->backgroundColor = color; + d_ptr->backgroundColor = color; update(); } -QColor DashBoardWidget::backgroundColor() const +auto DashBoardWidget::backgroundColor() const -> QColor { - return d->backgroundColor; + return d_ptr->backgroundColor; } void DashBoardWidget::paintEvent(QPaintEvent *event) @@ -197,9 +196,9 @@ void DashBoardWidget::paintEvent(QPaintEvent *event) painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing); // 背景 - if (d->backgroundColor != Qt::transparent) { + if (d_ptr->backgroundColor != Qt::transparent) { painter.setPen(Qt::NoPen); - painter.fillRect(rect(), d->backgroundColor); + painter.fillRect(rect(), d_ptr->backgroundColor); } // 平移中心 @@ -223,27 +222,26 @@ void DashBoardWidget::paintEvent(QPaintEvent *event) void DashBoardWidget::onStartAnimation(const double value) { - if(value < d->minValue - || value > d->maxValue - || value == d->value) + if (value < d_ptr->minValue || value > d_ptr->maxValue || value == d_ptr->value) { return; - - int start = d->value; +} + + int start = d_ptr->value; int end = value; - - d->animation->setStartValue(start); - d->animation->setEndValue(end); - d->animation->start(); + + d_ptr->animation->setStartValue(start); + d_ptr->animation->setEndValue(end); + d_ptr->animation->start(); } -double DashBoardWidget::value() const +auto DashBoardWidget::value() const -> double { - return d->value; + return d_ptr->value; } void DashBoardWidget::setValue(const double value) { - d->value = value; + d_ptr->value = value; update(); } @@ -258,27 +256,27 @@ void DashBoardWidget::drawArc(QPainter *painter) pen.setCapStyle(Qt::FlatCap); // 圆弧背景 - double angle = d->endAngle - d->startAngle; - pen.setColor(d->arcColor); + double angle = d_ptr->endAngle - d_ptr->startAngle; + pen.setColor(d_ptr->arcColor); painter->setPen(pen); - painter->drawArc(rect, d->startAngle * 16, angle * 16); + painter->drawArc(rect, d_ptr->startAngle * 16, angle * 16); } void DashBoardWidget::drawScale(QPainter *painter) { painter->save(); - - painter->rotate(270 - d->endAngle); - int steps = (d->scaleMajor * d->scaleMinor); - double angleStep = (d->endAngle - d->startAngle) / steps; + + painter->rotate(270 - d_ptr->endAngle); + int steps = (d_ptr->scaleMajor * d_ptr->scaleMinor); + double angleStep = (d_ptr->endAngle - d_ptr->startAngle) / steps; double min = qMin(width(), height()); double radius = min / 3; - - QPen pen(d->scaleColor); + + QPen pen(d_ptr->scaleColor); pen.setCapStyle(Qt::RoundCap); for (int i = 0; i <= steps; i++) { - if (i % d->scaleMinor == 0) { + if (i % d_ptr->scaleMinor == 0) { pen.setWidthF(1.5); painter->setPen(pen); painter->drawLine(0, radius - 8, 0, radius + 5); @@ -297,20 +295,20 @@ void DashBoardWidget::drawScale(QPainter *painter) void DashBoardWidget::drawScaleNum(QPainter *painter) { painter->save(); - painter->setPen(d->scaleColor); + painter->setPen(d_ptr->scaleColor); double min = qMin(width(), height()); double radius = min / 2.4; QFont font("Microsoft YaHei", min / 25); painter->setFont(font); - - double startRad = d->endAngle * (M_PI / 180); - double deltaRad = (d->endAngle - d->startAngle) * (M_PI / 180) / d->scaleMajor; + + double startRad = d_ptr->endAngle * (M_PI / 180); + double deltaRad = (d_ptr->endAngle - d_ptr->startAngle) * (M_PI / 180) / d_ptr->scaleMajor; QFontMetrics fontMetrics(font); - for (int i = 0; i <= d->scaleMajor; i++) { + for (int i = 0; i <= d_ptr->scaleMajor; i++) { double sina = qSin(startRad - i * deltaRad); double cosa = qCos(startRad - i * deltaRad); - double value = 1.0 * i * ((d->maxValue - d->minValue) / d->scaleMajor) + d->minValue; + double value = 1.0 * i * ((d_ptr->maxValue - d_ptr->minValue) / d_ptr->scaleMajor) + d_ptr->minValue; QString strValue = QString("%1").arg(value, 0, 'f', 2); double textWidth = fontMetrics.horizontalAdvance(strValue); @@ -327,16 +325,16 @@ void DashBoardWidget::drawPointer(QPainter *painter) { painter->save(); painter->setPen(Qt::NoPen); - painter->setBrush(d->pointerColor); + painter->setBrush(d_ptr->pointerColor); double radius = qMin(width(), height()) / 3.0; QPolygonF pts; - pts << QPointF(-5, 0) << QPointF(0, -8) - << QPointF(5, 0) << QPointF(0, radius); - - painter->rotate(270 - d->endAngle); - double degRotate = (d->endAngle - d->startAngle) / (d->maxValue - d->minValue) * (d->value - d->minValue); + pts << QPointF(-5, 0) << QPointF(0, -8) << QPointF(5, 0) << QPointF(0, radius); + + painter->rotate(270 - d_ptr->endAngle); + double degRotate = (d_ptr->endAngle - d_ptr->startAngle) / (d_ptr->maxValue - d_ptr->minValue) + * (d_ptr->value - d_ptr->minValue); painter->rotate(degRotate); painter->drawConvexPolygon(pts); @@ -346,22 +344,22 @@ void DashBoardWidget::drawPointer(QPainter *painter) void DashBoardWidget::drawValue(QPainter *painter) { painter->save(); - painter->setPen(d->textColor); + painter->setPen(d_ptr->textColor); double min = qMin(width(), height()); double radius = min / 2.0 - min / 4.8; QFont font("Microsoft YaHei", min / 25); painter->setFont(font); - - QString strValue = QString("%1").arg(d->value, 0, 'f', 2); - strValue = QString("%1 %2").arg(strValue, d->unit); + + QString strValue = QString("%1").arg(d_ptr->value, 0, 'f', 2); + strValue = QString("%1 %2").arg(strValue, d_ptr->unit); QRectF valueRect(-radius, radius / 2.5, radius * 2, radius / 3.5); painter->drawText(valueRect, Qt::AlignCenter, strValue); QRectF textRect(-radius, radius / 1.5, radius * 2, radius / 2.5); //font.setPixelSize(12); painter->setFont(font); - painter->drawText(textRect, Qt::AlignCenter, d->text); + painter->drawText(textRect, Qt::AlignCenter, d_ptr->text); painter->restore(); } diff --git a/DashBoard/dashboardwidget.h b/DashBoard/dashboardwidget.h index dd44e2c..0e9aeb4 100644 --- a/DashBoard/dashboardwidget.h +++ b/DashBoard/dashboardwidget.h @@ -3,7 +3,6 @@ #include -struct DashBoardWidgetPrivate; class DashBoardWidget : public QWidget { Q_OBJECT @@ -23,52 +22,52 @@ class DashBoardWidget : public QWidget Q_PROPERTY(QColor backgroundColor READ backgroundColor WRITE setBackgroundColor) public: explicit DashBoardWidget(QWidget *parent = nullptr); - ~DashBoardWidget(); + ~DashBoardWidget() override; - QSize sizeHint() const override; - QSize minimumSizeHint() const override; + [[nodiscard]] auto sizeHint() const -> QSize override; + [[nodiscard]] auto minimumSizeHint() const -> QSize override; - double value() const; + [[nodiscard]] auto value() const -> double; void setValue(const double value); void setMin(const double min); - double min() const; + [[nodiscard]] auto min() const -> double; void setmax(const double max); - double max() const; + [[nodiscard]] auto max() const -> double; void setStartAngle(const double startAngle); - double startAngle() const; + [[nodiscard]] auto startAngle() const -> double; void setEndAngle(const double endAngle); - double endAngle() const; + [[nodiscard]] auto endAngle() const -> double; void setScaleMajor(const int scale); - int scaleMajor() const; + [[nodiscard]] auto scaleMajor() const -> int; void setScaleMinor(const int scale); - int scaleMinor() const; + [[nodiscard]] auto scaleMinor() const -> int; void setUnit(const QString &unit); - QString unit() const; + [[nodiscard]] auto unit() const -> QString; void setText(const QString &text); - QString text() const; + [[nodiscard]] auto text() const -> QString; void setArcColor(const QColor &color); - QColor arcColor() const; + [[nodiscard]] auto arcColor() const -> QColor; void setScaleColor(const QColor &color); - QColor scaleColor() const; + [[nodiscard]] auto scaleColor() const -> QColor; void setPointerColor(const QColor &color); - QColor pointerColor() const; + [[nodiscard]] auto pointerColor() const -> QColor; void setTextColor(const QColor &color); - QColor textColor() const; + [[nodiscard]] auto textColor() const -> QColor; void setBackgroundColor(const QColor &color); - QColor backgroundColor() const; + [[nodiscard]] auto backgroundColor() const -> QColor; signals: void valueChanged(const double value); @@ -86,7 +85,8 @@ private slots: void drawPointer(QPainter *painter); void drawValue(QPainter *painter); - QScopedPointer d; + struct DashBoardWidgetPrivate; + QScopedPointer d_ptr; }; #endif // DASHBOARDWIDGET_H diff --git a/DashBoard/main.cpp b/DashBoard/main.cpp index fd3e533..24ba3b6 100644 --- a/DashBoard/main.cpp +++ b/DashBoard/main.cpp @@ -2,7 +2,7 @@ #include -int main(int argc, char *argv[]) +auto main(int argc, char *argv[]) -> int { QApplication a(argc, argv); MainWindow w; diff --git a/DashBoard/mainwindow.h b/DashBoard/mainwindow.h index d147190..b50d227 100644 --- a/DashBoard/mainwindow.h +++ b/DashBoard/mainwindow.h @@ -8,7 +8,7 @@ class MainWindow : public QMainWindow Q_OBJECT public: - MainWindow(QWidget *parent = nullptr); - ~MainWindow(); + explicit MainWindow(QWidget *parent = nullptr); + ~MainWindow() override; }; #endif // MAINWINDOW_H diff --git a/DragDrop/draglistwidget.cpp b/DragDrop/draglistwidget.cpp index db72eba..e748fc1 100644 --- a/DragDrop/draglistwidget.cpp +++ b/DragDrop/draglistwidget.cpp @@ -1,11 +1,9 @@ #include "draglistwidget.h" DragListWidget::DragListWidget(QWidget *parent) - :QListWidget(parent) + : QListWidget(parent) { setDragEnabled(true); - QStringList list; - list << tr("Hello") << tr("World") << tr("Good") << - tr("Study") << tr("Day") << tr("Up"); + QStringList list{tr("Hello"), tr("World"), tr("Good"), tr("Study"), tr("Day"), tr("Up")}; addItems(list); } diff --git a/DragDrop/draglistwidget.h b/DragDrop/draglistwidget.h index db135e9..9493a99 100644 --- a/DragDrop/draglistwidget.h +++ b/DragDrop/draglistwidget.h @@ -7,7 +7,7 @@ class DragListWidget : public QListWidget { Q_OBJECT public: - DragListWidget(QWidget *parent = nullptr); + explicit DragListWidget(QWidget *parent = nullptr); }; #endif // DRAGLISTWIDGET_H diff --git a/DragDrop/droplistwidget.cpp b/DragDrop/droplistwidget.cpp index 29edd50..5d4a520 100644 --- a/DragDrop/droplistwidget.cpp +++ b/DragDrop/droplistwidget.cpp @@ -3,7 +3,7 @@ #include DropListWidget::DropListWidget(QWidget *parent) - :QListWidget(parent) + : QListWidget(parent) { setDragEnabled(true); setAcceptDrops(true); @@ -13,14 +13,15 @@ DropListWidget::DropListWidget(QWidget *parent) void DropListWidget::setupUI() { - menu = new QMenu(this); - menu->addAction(tr("delete"), this, [this]{ + m_menu = new QMenu(this); + m_menu->addAction(tr("delete"), this, [this] { removeItemWidget(currentItem()); delete currentItem(); }); - connect(this, &DropListWidget::customContextMenuRequested, this, [this]{ - if (!currentItem()) + connect(this, &DropListWidget::customContextMenuRequested, this, [this] { + if (!currentItem()) { return; - menu->exec(QCursor::pos()); + } + m_menu->exec(QCursor::pos()); }); } diff --git a/DragDrop/droplistwidget.h b/DragDrop/droplistwidget.h index 97770bb..73d0e6e 100644 --- a/DragDrop/droplistwidget.h +++ b/DragDrop/droplistwidget.h @@ -7,11 +7,12 @@ class DropListWidget : public QListWidget { Q_OBJECT public: - DropListWidget(QWidget *parent = nullptr); + explicit DropListWidget(QWidget *parent = nullptr); private: void setupUI(); - QMenu *menu; + + QMenu *m_menu; }; #endif // DROPLISTWIDGET_H diff --git a/DragDrop/main.cpp b/DragDrop/main.cpp index fd3e533..24ba3b6 100644 --- a/DragDrop/main.cpp +++ b/DragDrop/main.cpp @@ -2,7 +2,7 @@ #include -int main(int argc, char *argv[]) +auto main(int argc, char *argv[]) -> int { QApplication a(argc, argv); MainWindow w; diff --git a/DragDrop/mainwindow.h b/DragDrop/mainwindow.h index 3a3484e..e8b9e0b 100644 --- a/DragDrop/mainwindow.h +++ b/DragDrop/mainwindow.h @@ -11,7 +11,7 @@ class MainWindow : public QMainWindow Q_OBJECT public: - MainWindow(QWidget *parent = nullptr); + explicit MainWindow(QWidget *parent = nullptr); protected: void dragEnterEvent(QDragEnterEvent *event) override; diff --git a/FlowLayout/flowlayout.cpp b/FlowLayout/flowlayout.cpp index 9a48855..35e35e2 100644 --- a/FlowLayout/flowlayout.cpp +++ b/FlowLayout/flowlayout.cpp @@ -53,13 +53,16 @@ #include "flowlayout.h" //! [1] FlowLayout::FlowLayout(QWidget *parent, int margin, int hSpacing, int vSpacing) - : QLayout(parent), m_hSpace(hSpacing), m_vSpace(vSpacing) + : QLayout(parent) + , m_hSpace(hSpacing) + , m_vSpace(vSpacing) { setContentsMargins(margin, margin, margin, margin); } FlowLayout::FlowLayout(int margin, int hSpacing, int vSpacing) - : m_hSpace(hSpacing), m_vSpace(vSpacing) + : m_hSpace(hSpacing) + , m_vSpace(vSpacing) { setContentsMargins(margin, margin, margin, margin); } @@ -69,8 +72,9 @@ FlowLayout::FlowLayout(int margin, int hSpacing, int vSpacing) FlowLayout::~FlowLayout() { QLayoutItem *item; - while ((item = takeAt(0))) + while ((item = takeAt(0))) { delete item; + } } //! [2] @@ -82,7 +86,7 @@ void FlowLayout::addItem(QLayoutItem *item) //! [3] //! [4] -int FlowLayout::horizontalSpacing() const +auto FlowLayout::horizontalSpacing() const -> int { if (m_hSpace >= 0) { return m_hSpace; @@ -91,7 +95,7 @@ int FlowLayout::horizontalSpacing() const } } -int FlowLayout::verticalSpacing() const +auto FlowLayout::verticalSpacing() const -> int { if (m_vSpace >= 0) { return m_vSpace; @@ -102,20 +106,21 @@ int FlowLayout::verticalSpacing() const //! [4] //! [5] -int FlowLayout::count() const +auto FlowLayout::count() const -> int { return itemList.size(); } -QLayoutItem *FlowLayout::itemAt(int index) const +auto FlowLayout::itemAt(int index) const -> QLayoutItem * { return itemList.value(index); } -QLayoutItem *FlowLayout::takeAt(int index) +auto FlowLayout::takeAt(int index) -> QLayoutItem * { - if (index >= 0 && index < itemList.size()) + if (index >= 0 && index < itemList.size()) { return itemList.takeAt(index); + } return nullptr; } //! [5] @@ -123,17 +128,17 @@ QLayoutItem *FlowLayout::takeAt(int index) //! [6] Qt::Orientations FlowLayout::expandingDirections() const { - return { }; + return {}; } //! [6] //! [7] -bool FlowLayout::hasHeightForWidth() const +auto FlowLayout::hasHeightForWidth() const -> bool { return true; } -int FlowLayout::heightForWidth(int width) const +auto FlowLayout::heightForWidth(int width) const -> int { int height = doLayout(QRect(0, 0, width, 0), true); return height; @@ -147,12 +152,12 @@ void FlowLayout::setGeometry(const QRect &rect) doLayout(rect, false); } -QSize FlowLayout::sizeHint() const +auto FlowLayout::sizeHint() const -> QSize { return minimumSize(); } -QSize FlowLayout::minimumSize() const +auto FlowLayout::minimumSize() const -> QSize { QSize size; for (const QLayoutItem *item : qAsConst(itemList)) @@ -165,7 +170,7 @@ QSize FlowLayout::minimumSize() const //! [8] //! [9] -int FlowLayout::doLayout(const QRect &rect, bool testOnly) const +auto FlowLayout::doLayout(const QRect &rect, bool testOnly) const -> int { int left, top, right, bottom; getContentsMargins(&left, &top, &right, &bottom); @@ -173,21 +178,23 @@ int FlowLayout::doLayout(const QRect &rect, bool testOnly) const int x = effectiveRect.x(); int y = effectiveRect.y(); int lineHeight = 0; -//! [9] + //! [9] -//! [10] + //! [10] for (QLayoutItem *item : qAsConst(itemList)) { const QWidget *wid = item->widget(); int spaceX = horizontalSpacing(); if (spaceX == -1) - spaceX = wid->style()->layoutSpacing( - QSizePolicy::PushButton, QSizePolicy::PushButton, Qt::Horizontal); + spaceX = wid->style()->layoutSpacing(QSizePolicy::PushButton, + QSizePolicy::PushButton, + Qt::Horizontal); int spaceY = verticalSpacing(); if (spaceY == -1) - spaceY = wid->style()->layoutSpacing( - QSizePolicy::PushButton, QSizePolicy::PushButton, Qt::Vertical); -//! [10] -//! [11] + spaceY = wid->style()->layoutSpacing(QSizePolicy::PushButton, + QSizePolicy::PushButton, + Qt::Vertical); + //! [10] + //! [11] int nextX = x + item->sizeHint().width() + spaceX; if (nextX - spaceX > effectiveRect.right() && lineHeight > 0) { x = effectiveRect.x(); @@ -206,7 +213,7 @@ int FlowLayout::doLayout(const QRect &rect, bool testOnly) const } //! [11] //! [12] -int FlowLayout::smartSpacing(QStyle::PixelMetric pm) const +auto FlowLayout::smartSpacing(QStyle::PixelMetric pm) const -> int { QObject *parent = this->parent(); if (!parent) { diff --git a/FlowLayout/flowlayout.h b/FlowLayout/flowlayout.h index 3155d5d..727d1ae 100644 --- a/FlowLayout/flowlayout.h +++ b/FlowLayout/flowlayout.h @@ -60,24 +60,24 @@ class FlowLayout : public QLayout public: explicit FlowLayout(QWidget *parent, int margin = -1, int hSpacing = -1, int vSpacing = -1); explicit FlowLayout(int margin = -1, int hSpacing = -1, int vSpacing = -1); - ~FlowLayout(); + ~FlowLayout() override; void addItem(QLayoutItem *item) override; - int horizontalSpacing() const; - int verticalSpacing() const; - Qt::Orientations expandingDirections() const override; - bool hasHeightForWidth() const override; - int heightForWidth(int) const override; - int count() const override; - QLayoutItem *itemAt(int index) const override; - QSize minimumSize() const override; + [[nodiscard]] auto horizontalSpacing() const -> int; + [[nodiscard]] auto verticalSpacing() const -> int; + [[nodiscard]] Qt::Orientations expandingDirections() const override; + [[nodiscard]] auto hasHeightForWidth() const -> bool override; + [[nodiscard]] auto heightForWidth(int) const -> int override; + [[nodiscard]] auto count() const -> int override; + [[nodiscard]] auto itemAt(int index) const -> QLayoutItem * override; + [[nodiscard]] auto minimumSize() const -> QSize override; void setGeometry(const QRect &rect) override; - QSize sizeHint() const override; - QLayoutItem *takeAt(int index) override; + [[nodiscard]] auto sizeHint() const -> QSize override; + auto takeAt(int index) -> QLayoutItem * override; private: - int doLayout(const QRect &rect, bool testOnly) const; - int smartSpacing(QStyle::PixelMetric pm) const; + [[nodiscard]] auto doLayout(const QRect &rect, bool testOnly) const -> int; + [[nodiscard]] auto smartSpacing(QStyle::PixelMetric pm) const -> int; QList itemList; int m_hSpace; diff --git a/FlowLayout/flowwidget.cc b/FlowLayout/flowwidget.cc index fbf4b1e..bb4ced1 100644 --- a/FlowLayout/flowwidget.cc +++ b/FlowLayout/flowwidget.cc @@ -34,12 +34,12 @@ class FlowWidget::FlowWidgetPrivate { public: FlowWidgetPrivate(QWidget *parent) - : owner(parent) + : q_ptr(parent) { - flowLayout = new FlowLayout(owner, 9, 5, 5); + flowLayout = new FlowLayout(q_ptr, 9, 5, 5); } - QWidget *owner; + QWidget *q_ptr; FlowLayout *flowLayout; }; diff --git a/FlowLayout/flowwidget.hpp b/FlowLayout/flowwidget.hpp index 2aa4300..4973141 100644 --- a/FlowLayout/flowwidget.hpp +++ b/FlowLayout/flowwidget.hpp @@ -16,7 +16,7 @@ class LabelWidget : public QWidget public: explicit LabelWidget(const QString &text, QWidget *parent); - QString text() const; + [[nodiscard]] auto text() const -> QString; signals: void removed(); @@ -30,12 +30,12 @@ class FlowWidget : public QWidget Q_OBJECT public: explicit FlowWidget(QWidget *parent = nullptr); - ~FlowWidget(); + ~FlowWidget() override; void setItems(const QStringList &list); void addItem(const QString &text); - QStringList items() const; + [[nodiscard]] auto items() const -> QStringList; private slots: void onRemoved(); diff --git a/FlowLayout/main.cc b/FlowLayout/main.cc index e9bbf59..5d48a9d 100644 --- a/FlowLayout/main.cc +++ b/FlowLayout/main.cc @@ -7,7 +7,7 @@ #include #endif -int main(int argc, char *argv[]) +auto main(int argc, char *argv[]) -> int { QApplication a(argc, argv); MainWindow w; diff --git a/FlowLayout/mainwindow.hpp b/FlowLayout/mainwindow.hpp index 2a84cf2..ebd3d81 100644 --- a/FlowLayout/mainwindow.hpp +++ b/FlowLayout/mainwindow.hpp @@ -1,19 +1,14 @@ #ifndef MAINWINDOW_HPP #define MAINWINDOW_HPP -#include -#if QT_VERSION >= 0x050000 -#include -#else -#include -#endif +#include class MainWindow : public QMainWindow { Q_OBJECT - public: - MainWindow(QWidget *parent = nullptr); - ~MainWindow(); +public: + explicit MainWindow(QWidget *parent = nullptr); + ~MainWindow() override; }; #endif // MAINWINDOW_HPP diff --git a/GridViewModel/gridmodel.cpp b/GridViewModel/gridmodel.cpp index e172c7b..2a40b36 100644 --- a/GridViewModel/gridmodel.cpp +++ b/GridViewModel/gridmodel.cpp @@ -2,24 +2,22 @@ #include -GridModel::GridModel(QObject* parent) +GridModel::GridModel(QObject *parent) : QAbstractListModel(parent) -{ - -} +{} -QVariant GridModel::data(const QModelIndex &index, int role) const +auto GridModel::data(const QModelIndex &index, int role) const -> QVariant { ImageInfo *image = m_imageVector.at(index.row()); - switch(role){ + switch (role) { case Qt::DecorationRole: return image->image; //case Qt::DisplayRole: return image->filename; - case Qt::ToolTipRole:return image->color; + case Qt::ToolTipRole: return image->color; case Qt::SizeHintRole: return QSize(WIDTH, WIDTH); case Qt::TextAlignmentRole: return Qt::AlignCenter; default: break; } - return QVariant(); + return {}; } diff --git a/GridViewModel/gridmodel.h b/GridViewModel/gridmodel.h index 1f5785f..7138a52 100644 --- a/GridViewModel/gridmodel.h +++ b/GridViewModel/gridmodel.h @@ -6,27 +6,32 @@ #define WIDTH 80 -struct ImageInfo{ +struct ImageInfo +{ QImage image; QString color; }; -typedef QVector ImageVector; +using ImageVector = QVector; class GridModel : public QAbstractListModel { public: - GridModel(QObject* parent = nullptr); - int rowCount(const QModelIndex & = QModelIndex()) const override - { return m_imageVector.size(); } - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + explicit GridModel(QObject *parent = nullptr); + [[nodiscard]] auto rowCount(const QModelIndex & = QModelIndex()) const -> int override + { + return m_imageVector.size(); + } + [[nodiscard]] auto data(const QModelIndex &index, int role = Qt::DisplayRole) const + -> QVariant override; - void setImageVector(const ImageVector& imageVector) + void setImageVector(const ImageVector &imageVector) { beginResetModel(); m_imageVector = imageVector; endResetModel(); } + private: ImageVector m_imageVector; }; diff --git a/GridViewModel/gridview.cpp b/GridViewModel/gridview.cpp index 82f4290..37c0ce2 100644 --- a/GridViewModel/gridview.cpp +++ b/GridViewModel/gridview.cpp @@ -12,8 +12,9 @@ GridView::GridView(QWidget *parent) void GridView::onSelectChanged() { QItemSelectionModel *selModel = selectionModel(); - if(!selModel) + if (!selModel) { return; + } qDebug() << selModel->selectedIndexes(); } @@ -32,5 +33,8 @@ void GridView::setupUI() void GridView::buildConnect() { - connect(selectionModel(), &QItemSelectionModel::selectionChanged, this, &GridView::onSelectChanged); + connect(selectionModel(), + &QItemSelectionModel::selectionChanged, + this, + &GridView::onSelectChanged); } diff --git a/GridViewModel/gridview.h b/GridViewModel/gridview.h index 77315de..a9bcb5e 100644 --- a/GridViewModel/gridview.h +++ b/GridViewModel/gridview.h @@ -8,10 +8,12 @@ class GridView : public QListView { public: - GridView(QWidget* parent = nullptr); + explicit GridView(QWidget *parent = nullptr); - void setImageVector(const ImageVector& imageVector) - { m_gridModel->setImageVector(imageVector); } + void setImageVector(const ImageVector &imageVector) + { + m_gridModel->setImageVector(imageVector); + } private slots: void onSelectChanged(); diff --git a/GridViewModel/main.cpp b/GridViewModel/main.cpp index fd3e533..24ba3b6 100644 --- a/GridViewModel/main.cpp +++ b/GridViewModel/main.cpp @@ -2,7 +2,7 @@ #include -int main(int argc, char *argv[]) +auto main(int argc, char *argv[]) -> int { QApplication a(argc, argv); MainWindow w; diff --git a/GridViewModel/mainwindow.h b/GridViewModel/mainwindow.h index dad3811..4e0ea3b 100644 --- a/GridViewModel/mainwindow.h +++ b/GridViewModel/mainwindow.h @@ -10,8 +10,8 @@ class MainWindow : public QMainWindow Q_OBJECT public: - MainWindow(QWidget *parent = nullptr); - ~MainWindow(); + explicit MainWindow(QWidget *parent = nullptr); + ~MainWindow() override; private: void setupUI(); diff --git a/HttpClient/httpclient.cpp b/HttpClient/httpclient.cpp index 50b58c4..59ddd33 100644 --- a/HttpClient/httpclient.cpp +++ b/HttpClient/httpclient.cpp @@ -10,15 +10,17 @@ enum Method { GET, POST, PUT, DELETE }; -class HttpClientPrivate +class HttpClient::HttpClientPrivate { public: - HttpClientPrivate(QObject *parent) - : owner(parent) + explicit HttpClientPrivate(QObject *parent) + : q_ptr(parent) { - manager = new QNetworkAccessManager(owner); + manager = new QNetworkAccessManager(q_ptr); } - QObject *owner; + + QObject *q_ptr; + QNetworkAccessManager *manager; HttpClient::HttpHeaders headers; QString url; @@ -31,56 +33,58 @@ class HttpClientPrivate HttpClient::HttpClient(QObject *parent) : QObject(parent) - , d(new HttpClientPrivate(this)) + , d_ptr(new HttpClientPrivate(this)) {} -HttpClient::~HttpClient() {} +HttpClient::~HttpClient() = default; void HttpClient::setHeaders(const HttpClient::HttpHeaders &headers) { - d->headers = headers; + d_ptr->headers = headers; } void HttpClient::setJson(const QString &json) { - d->json = json; + d_ptr->json = json; } void HttpClient::setParams(const HttpClient::HttpParams ¶ms) { - for (HttpParams::const_iterator iter = params.begin(); iter != params.end(); iter++) - d->params.addQueryItem(iter.key(), iter.value().toString()); + for (HttpParams::const_iterator iter = params.begin(); iter != params.end(); iter++) { + d_ptr->params.addQueryItem(iter.key(), iter.value().toString()); + } } void HttpClient::get(const QString &url) { - d->method = GET; + d_ptr->method = GET; startRequest(url); } void HttpClient::post(const QString &url) { - d->method = POST; + d_ptr->method = POST; startRequest(url); } void HttpClient::put(const QString &url) { - d->method = PUT; + d_ptr->method = PUT; startRequest(url); } void HttpClient::remove(const QString &url) { - d->method = DELETE; + d_ptr->method = DELETE; startRequest(url); } void HttpClient::download(const QString &url, const QString &savePath) { - if (url.isEmpty() || !QUrl(url).isValid()) + if (url.isEmpty() || !QUrl(url).isValid()) { return; - d->url = url; + } + d_ptr->url = url; if (QFileInfo::exists(savePath)) { qWarning() << tr("[Error] File already exists: %1.").arg(savePath); @@ -94,18 +98,21 @@ void HttpClient::download(const QString &url, const QString &savePath) return; } QNetworkRequest request = createRequest(); - QNetworkReply *reply = d->manager->get(request); - if (!reply) + QNetworkReply *reply = d_ptr->manager->get(request); + if (!reply) { return; + } connect(reply, &QNetworkReply::readyRead, this, [=] { - if (reply->bytesAvailable() > 0) + if (reply->bytesAvailable() > 0) { file->write(reply->readAll()); + } }); connect(reply, &QNetworkReply::finished, this, [=] { - if (reply->bytesAvailable() > 0) + if (reply->bytesAvailable() > 0) { file->write(reply->readAll()); + } delete file; reply->deleteLater(); emit finish(); @@ -123,8 +130,9 @@ void HttpClient::upload(const QString &url, const QString &path) void HttpClient::upload(const QString &url, const QStringList &paths) { - if (paths.isEmpty()) + if (paths.isEmpty()) { return; + } QHttpMultiPart *multiPart = initMultiPart(url); QString inputName = paths.size() == 1 ? "file" @@ -158,8 +166,9 @@ void HttpClient::upload(const QString &url, const QStringList &paths) void HttpClient::upload(const QString &url, const QByteArray &data) { - if (data.isEmpty()) + if (data.isEmpty()) { return; + } QHttpMultiPart *multiPart = initMultiPart(url); @@ -176,11 +185,13 @@ void HttpClient::slotReadyRead() { qDebug() << "slotReadyRead"; QNetworkReply *reply = qobject_cast(sender()); - if (!reply) + if (!reply) { return; + } - if (reply->bytesAvailable() <= 0) + if (reply->bytesAvailable() <= 0) { return; + } QByteArray buf = reply->readAll(); qDebug() << buf.size(); @@ -191,11 +202,13 @@ void HttpClient::slotReplyFinish() { qDebug() << "slotReplyFinish"; QNetworkReply *reply = qobject_cast(sender()); - if (!reply) + if (!reply) { return; + } - if (reply->bytesAvailable() > 0) + if (reply->bytesAvailable() > 0) { emit readyReady(reply->readAll()); + } reply->deleteLater(); reply = nullptr; @@ -206,11 +219,13 @@ void HttpClient::slotReplyFinish() void HttpClient::slotError(QNetworkReply::NetworkError replyError) { QNetworkReply *reply = qobject_cast(sender()); - if (!reply) + if (!reply) { return; + } - if (replyError == QNetworkReply::NoError) + if (replyError == QNetworkReply::NoError) { return; + } emit error(reply->errorString()); } @@ -218,19 +233,21 @@ void HttpClient::slotError(QNetworkReply::NetworkError replyError) void HttpClient::slotSslErrors(const QList &errors) { QNetworkReply *reply = qobject_cast(sender()); - if (!reply) + if (!reply) { return; + } qDebug() << errors; } -QHttpMultiPart *HttpClient::initMultiPart(const QString &url) +auto HttpClient::initMultiPart(const QString &url) -> QHttpMultiPart * { - if (url.isEmpty() || !QUrl(url).isValid()) + if (url.isEmpty() || !QUrl(url).isValid()) { return nullptr; - d->url = url; + } + d_ptr->url = url; QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType, this); - QList> paramItems = d->params.queryItems(); + QList> paramItems = d_ptr->params.queryItems(); for (int i = 0; i < paramItems.size(); ++i) { QString name = paramItems.at(i).first; QString value = paramItems.at(i).second; @@ -248,9 +265,10 @@ QHttpMultiPart *HttpClient::initMultiPart(const QString &url) void HttpClient::execUpload(QHttpMultiPart *multiPart) { QNetworkRequest request = createRequest(); - QNetworkReply *reply = d->manager->post(request, multiPart); - if (!reply) + QNetworkReply *reply = d_ptr->manager->post(request, multiPart); + if (!reply) { return; + } multiPart->setParent(reply); // delete the multiPart with the reply connect(reply, &QNetworkReply::finished, this, [this, reply] { reply->deleteLater(); @@ -263,9 +281,10 @@ void HttpClient::execUpload(QHttpMultiPart *multiPart) void HttpClient::startRequest(const QString &url) { - if (url.isEmpty() || !QUrl(url).isValid()) + if (url.isEmpty() || !QUrl(url).isValid()) { return; - d->url = url; + } + d_ptr->url = url; execRequest(); } @@ -274,39 +293,41 @@ void HttpClient::execRequest() QNetworkRequest request = createRequest(); QNetworkReply *reply = nullptr; - switch (d->method) { - case GET: reply = d->manager->get(request); break; + switch (d_ptr->method) { + case GET: reply = d_ptr->manager->get(request); break; case POST: - reply = d->manager->post(request, - d->useJson ? d->json.toUtf8() - : d->params.toString(QUrl::FullyEncoded).toUtf8()); + reply = d_ptr->manager->post(request, + d_ptr->useJson + ? d_ptr->json.toUtf8() + : d_ptr->params.toString(QUrl::FullyEncoded).toUtf8()); break; case PUT: - reply = d->manager->put(request, - d->useJson ? d->json.toUtf8() - : d->params.toString(QUrl::FullyEncoded).toUtf8()); + reply = d_ptr->manager->put(request, + d_ptr->useJson + ? d_ptr->json.toUtf8() + : d_ptr->params.toString(QUrl::FullyEncoded).toUtf8()); break; - case DELETE: reply = d->manager->deleteResource(request); break; + case DELETE: reply = d_ptr->manager->deleteResource(request); break; default: return; } buildConnect(reply); } -QNetworkRequest HttpClient::createRequest() +auto HttpClient::createRequest() -> QNetworkRequest { - bool get = d->method == GET; - bool withForm = !get && !d->useJson; // PUT、POST 或者 DELETE 请求,且 useJson 为 false - bool withJson = !get && d->useJson; // PUT、POST 或者 DELETE 请求,且 useJson 为 true + bool get = d_ptr->method == GET; + bool withForm = !get && !d_ptr->useJson; // PUT、POST 或者 DELETE 请求,且 useJson 为 false + bool withJson = !get && d_ptr->useJson; // PUT、POST 或者 DELETE 请求,且 useJson 为 true - if (get && !d->params.isEmpty()) { - d->url += "?" + d->params.toString(QUrl::FullyEncoded); + if (get && !d_ptr->params.isEmpty()) { + d_ptr->url += "?" + d_ptr->params.toString(QUrl::FullyEncoded); } - qDebug() << tr("URL: ") << d->url; + qDebug() << tr("URL: ") << d_ptr->url; if (withForm) { - QList> paramItems = d->params.queryItems(); + QList> paramItems = d_ptr->params.queryItems(); QString buffer; // 避免多次调用 qDebug() 输入调试信息,每次 qDebug() 都有可能输出行号等 // 按键值对的方式输出参数 @@ -314,27 +335,29 @@ QNetworkRequest HttpClient::createRequest() QString name = paramItems.at(i).first; QString value = paramItems.at(i).second; - if (0 == i) + if (0 == i) { buffer += QString("params: %1=%2\n").arg(name, value); - else + } else { buffer += QString(" %1=%2\n").arg(name, value); + } } - if (!buffer.isEmpty()) + if (!buffer.isEmpty()) { qDebug() << buffer; + } } // [3] 设置 Content-Type // 如果是 POST 请求,useJson 为 true 时添加 Json 的请求头,useJson 为 false 时添加 Form 的请求头 if (withForm) { - d->headers["Content-Type"] = "application/x-www-form-urlencoded"; + d_ptr->headers["Content-Type"] = "application/x-www-form-urlencoded"; } else if (withJson) { - d->headers["Content-Type"] = "application/json; charset=utf-8"; + d_ptr->headers["Content-Type"] = "application/json; charset=utf-8"; } // [4] 添加请求头到 request 中 - QNetworkRequest request(QUrl(d->url)); - for (auto i = d->headers.cbegin(); i != d->headers.cend(); ++i) { + QNetworkRequest request(QUrl(d_ptr->url)); + for (auto i = d_ptr->headers.cbegin(); i != d_ptr->headers.cend(); ++i) { request.setRawHeader(i.key().toUtf8(), i.value().toUtf8()); } diff --git a/HttpClient/httpclient.h b/HttpClient/httpclient.h index ddfbc51..cddf547 100644 --- a/HttpClient/httpclient.h +++ b/HttpClient/httpclient.h @@ -4,16 +4,15 @@ #include #include -class HttpClientPrivate; class HttpClient : public QObject { Q_OBJECT public: - typedef QHash HttpHeaders; - typedef QMap HttpParams; + using HttpHeaders = QHash; + using HttpParams = QMap; explicit HttpClient(QObject *parent = nullptr); - ~HttpClient(); + ~HttpClient() override; public slots: void setHeaders(const HttpClient::HttpHeaders&); @@ -47,14 +46,15 @@ private slots: void slotSslErrors(const QList &errors); private: - QHttpMultiPart *initMultiPart(const QString &url); + auto initMultiPart(const QString &url) -> QHttpMultiPart *; void execUpload(QHttpMultiPart*); void startRequest(const QString &url); void execRequest(); - QNetworkRequest createRequest(); + auto createRequest() -> QNetworkRequest; void buildConnect(QNetworkReply *reply); - QScopedPointer d; + class HttpClientPrivate; + QScopedPointer d_ptr; }; #endif // HTTPCLIENT_H diff --git a/HttpClient/httpclientthread.cpp b/HttpClient/httpclientthread.cpp index e94d605..40dc2ad 100644 --- a/HttpClient/httpclientthread.cpp +++ b/HttpClient/httpclientthread.cpp @@ -8,7 +8,7 @@ HttpClientThread::HttpClientThread(QObject *parent) HttpClientThread::~HttpClientThread() { - if(isRunning()){ + if (isRunning()) { quit(); wait(); } @@ -27,17 +27,21 @@ void HttpClientThread::run() connect(this, &HttpClientThread::remove, httpClient.data(), &HttpClient::remove); connect(this, &HttpClientThread::download, httpClient.data(), &HttpClient::download); -// connect(this, SIGNAL(upload(const QString &url, const QString &path)), -// httpClient.data(), SLOT(upload(const QString &url, const QString &path))); -// connect(this, SIGNAL(upload(const QString &url, const QStringList &paths)), -// httpClient.data(), SLOT(upload(const QString &url, const QStringList &paths))); -// connect(this, SIGNAL(upload(const QString &url, const QByteArray &data)), -// httpClient.data(), SLOT(upload(const QString &url, const QByteArray &data))); + // connect(this, SIGNAL(upload(const QString &url, const QString &path)), + // httpClient.data(), SLOT(upload(const QString &url, const QString &path))); + // connect(this, SIGNAL(upload(const QString &url, const QStringList &paths)), + // httpClient.data(), SLOT(upload(const QString &url, const QStringList &paths))); + // connect(this, SIGNAL(upload(const QString &url, const QByteArray &data)), + // httpClient.data(), SLOT(upload(const QString &url, const QByteArray &data))); connect(httpClient.data(), &HttpClient::error, this, &HttpClientThread::error); connect(httpClient.data(), &HttpClient::readyReady, this, &HttpClientThread::readyReady); - connect(httpClient.data(), &HttpClient::downloadProgress, this, &HttpClientThread::downloadProgress); + connect(httpClient.data(), + &HttpClient::downloadProgress, + this, + &HttpClientThread::downloadProgress); connect(httpClient.data(), &HttpClient::uploadProgress, this, &HttpClientThread::uploadProgress); connect(httpClient.data(), &HttpClient::finish, this, &HttpClientThread::finish); + exec(); } diff --git a/HttpClient/httpclientthread.h b/HttpClient/httpclientthread.h index 766ed6e..7bf579e 100644 --- a/HttpClient/httpclientthread.h +++ b/HttpClient/httpclientthread.h @@ -9,13 +9,13 @@ class HttpClientThread : public QThread { Q_OBJECT public: - HttpClientThread(QObject *parent = nullptr); - ~HttpClientThread(); + explicit HttpClientThread(QObject *parent = nullptr); + ~HttpClientThread() override; signals: - void setHeaders(const HttpClient::HttpHeaders&); - void setJson(const QString& json); - void setParams(const HttpClient::HttpParams& params); + void setHeaders(const HttpClient::HttpHeaders &); + void setJson(const QString &json); + void setParams(const HttpClient::HttpParams ¶ms); void get(const QString &url); void post(const QString &url); @@ -31,8 +31,8 @@ class HttpClientThread : public QThread void upload(const QString &url, const QByteArray &data); //------------------------------------------------------------- - void error(const QString&); - void readyReady(const QByteArray&); + void error(const QString &); + void readyReady(const QByteArray &); void downloadProgress(qint64 bytesSent, qint64 bytesTotal); void uploadProgress(qint64 bytesSent, qint64 bytesTotal); void finish(); diff --git a/HttpClient/main.cpp b/HttpClient/main.cpp index fd3e533..24ba3b6 100644 --- a/HttpClient/main.cpp +++ b/HttpClient/main.cpp @@ -2,7 +2,7 @@ #include -int main(int argc, char *argv[]) +auto main(int argc, char *argv[]) -> int { QApplication a(argc, argv); MainWindow w; diff --git a/HttpClient/mainwindow.cpp b/HttpClient/mainwindow.cpp index 7df48b4..2f987fd 100644 --- a/HttpClient/mainwindow.cpp +++ b/HttpClient/mainwindow.cpp @@ -2,13 +2,15 @@ #include "httpclient.h" //#include "httpclientthread.h" -#include #include +#include -class MainWindowPrivate{ +class MainWindowPrivate +{ public: - MainWindowPrivate(QWidget *parent) - : owner(parent){ + explicit MainWindowPrivate(QWidget *parent) + : owner(parent) + { urlEdit = new QLineEdit(owner); urlEdit->setText("http://www.baidu.com"); urlEdit->setPlaceholderText(QObject::tr("http://url")); @@ -37,14 +39,12 @@ MainWindow::MainWindow(QWidget *parent) buildConnect(); } -MainWindow::~MainWindow() -{ -} +MainWindow::~MainWindow() {} void MainWindow::onRequest() { QString url = d->urlEdit->text(); - if(url.isEmpty() || !QUrl(url).isValid()) + if (url.isEmpty() || !QUrl(url).isValid()) return; d->requestButton->setEnabled(false); d->elapsedTimer.start(); @@ -66,18 +66,18 @@ void MainWindow::onAppendBytes(const QByteArray &bytes) void MainWindow::onAppendText() { - if(d->bytes.isEmpty()) + if (d->bytes.isEmpty()) return; - if(d->bytes.size() > 2000){ + if (d->bytes.size() > 2000) { d->textEdit->append(d->bytes.left(2000)); d->bytes.remove(0, 2000); - }else{ + } else { d->textEdit->append(d->bytes); d->bytes.clear(); } - if(d->bytes.isEmpty() && !d->requestButton->isChecked()) + if (d->bytes.isEmpty() && !d->requestButton->isChecked()) d->timer.stop(); } @@ -108,4 +108,3 @@ void MainWindow::buildConnect() // connect(d->httpClientThread, &HttpClientThread::error, d->textEdit, &QPlainTextEdit::appendPlainText); // connect(d->httpClientThread, &HttpClientThread::finish, this, &MainWindow::onFinish); } - diff --git a/HttpClient/mainwindow.h b/HttpClient/mainwindow.h index 9a0e114..a13d067 100644 --- a/HttpClient/mainwindow.h +++ b/HttpClient/mainwindow.h @@ -9,8 +9,8 @@ class MainWindow : public QMainWindow Q_OBJECT public: - MainWindow(QWidget *parent = nullptr); - ~MainWindow(); + explicit MainWindow(QWidget *parent = nullptr); + ~MainWindow() override; private slots: void onRequest(); diff --git a/LogAsynchronous/fileutil.cpp b/LogAsynchronous/fileutil.cpp index c575ac9..78aff9c 100644 --- a/LogAsynchronous/fileutil.cpp +++ b/LogAsynchronous/fileutil.cpp @@ -12,11 +12,12 @@ const static int kRollPerSeconds_ = 60 * 60 * 24; -bool generateDirectorys(const QString &directory) +auto generateDirectorys(const QString &directory) -> bool { QDir sourceDir(directory); - if (sourceDir.exists()) + if (sourceDir.exists()) { return true; +} QString tempDir; QStringList directorys = directory.split("/"); @@ -25,8 +26,9 @@ bool generateDirectorys(const QString &directory) tempDir += path + "/"; QDir dir(tempDir); - if (!dir.exists() && !dir.mkdir(tempDir)) + if (!dir.exists() && !dir.mkdir(tempDir)) { return false; +} } return true; @@ -79,7 +81,7 @@ void FileUtil::onFlush() d_ptr->stream.flush(); } -QString FileUtil::getFileName(qint64 *now) const +auto FileUtil::getFileName(qint64 *now) const -> QString { *now = QDateTime::currentSecsSinceEpoch(); QString data = QDateTime::fromSecsSinceEpoch(*now).toString("yyyy-MM-dd-hh-mm-ss"); @@ -92,7 +94,7 @@ QString FileUtil::getFileName(qint64 *now) const return filename; } -bool FileUtil::rollFile(int count) +auto FileUtil::rollFile(int count) -> bool { qint64 now = 0; QString filename = getFileName(&now); diff --git a/LogAsynchronous/fileutil.h b/LogAsynchronous/fileutil.h index cf07159..88aa5be 100644 --- a/LogAsynchronous/fileutil.h +++ b/LogAsynchronous/fileutil.h @@ -9,7 +9,7 @@ class FileUtil : public QObject Q_OBJECT public: explicit FileUtil(qint64 days = 30, QObject *parent = nullptr); - ~FileUtil(); + ~FileUtil() override; public slots: void onWrite(const QString &); @@ -18,8 +18,8 @@ private slots: void onFlush(); private: - QString getFileName(qint64 *now) const; - bool rollFile(int); + auto getFileName(qint64 *now) const -> QString; + auto rollFile(int) -> bool; void autoDelFile(); void setTimer(); diff --git a/LogAsynchronous/logasync.cpp b/LogAsynchronous/logasync.cpp index 2538f3b..fb98d2b 100644 --- a/LogAsynchronous/logasync.cpp +++ b/LogAsynchronous/logasync.cpp @@ -7,8 +7,9 @@ // 消息处理函数 void messageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg) { - if (type < LogAsync::instance()->logLevel()) + if (type < LogAsync::instance()->logLevel()) { return; +} FILE *stdPrint = stdout; QString level; @@ -78,7 +79,7 @@ struct LogAsyncPrivate QMutex LogAsync::m_mutex; -LogAsync *LogAsync::instance() +auto LogAsync::instance() -> LogAsync * { QMutexLocker locker(&m_mutex); static LogAsync log; @@ -90,7 +91,7 @@ void LogAsync::setOrientation(LogAsync::Orientation orientation) d_ptr->orientation = orientation; } -LogAsync::Orientation LogAsync::orientation() +auto LogAsync::orientation() -> LogAsync::Orientation { return d_ptr->orientation; } @@ -100,7 +101,7 @@ void LogAsync::setLogLevel(QtMsgType type) d_ptr->msgType = type; } -QtMsgType LogAsync::logLevel() +auto LogAsync::logLevel() -> QtMsgType { return d_ptr->msgType; } diff --git a/LogAsynchronous/logasync.h b/LogAsynchronous/logasync.h index 6429309..df0a1c2 100644 --- a/LogAsynchronous/logasync.h +++ b/LogAsynchronous/logasync.h @@ -11,13 +11,13 @@ class LogAsync : public QThread public: enum Orientation { Std = 1, File, StdAndFile }; - static LogAsync *instance(); + static auto instance() -> LogAsync *; void setOrientation(Orientation); - Orientation orientation(); + auto orientation() -> Orientation; void setLogLevel(QtMsgType); - QtMsgType logLevel(); + auto logLevel() -> QtMsgType; void startWork(); void stop(); @@ -29,7 +29,7 @@ class LogAsync : public QThread void run() override; private: - LogAsync(QObject *parent = nullptr); + explicit LogAsync(QObject *parent = nullptr); ~LogAsync() override; static QMutex m_mutex; diff --git a/LogAsynchronous/main.cpp b/LogAsynchronous/main.cpp index 0bddd25..4e79682 100644 --- a/LogAsynchronous/main.cpp +++ b/LogAsynchronous/main.cpp @@ -5,7 +5,7 @@ #include "logasync.h" #include "mainwindow.h" -int main(int argc, char *argv[]) +auto main(int argc, char *argv[]) -> int { QApplication a(argc, argv); diff --git a/LogAsynchronous/mainwindow.h b/LogAsynchronous/mainwindow.h index 6485032..a073161 100644 --- a/LogAsynchronous/mainwindow.h +++ b/LogAsynchronous/mainwindow.h @@ -8,8 +8,8 @@ class MainWindow : public QMainWindow { Q_OBJECT public: - MainWindow(QWidget *parent = nullptr); - ~MainWindow(); + explicit MainWindow(QWidget *parent = nullptr); + ~MainWindow() override; private: void testLog(); diff --git a/MulClient/main.cpp b/MulClient/main.cpp index fd3e533..24ba3b6 100644 --- a/MulClient/main.cpp +++ b/MulClient/main.cpp @@ -2,7 +2,7 @@ #include -int main(int argc, char *argv[]) +auto main(int argc, char *argv[]) -> int { QApplication a(argc, argv); MainWindow w; diff --git a/MulClient/mainwindow.cpp b/MulClient/mainwindow.cpp index 2811546..9a81d44 100644 --- a/MulClient/mainwindow.cpp +++ b/MulClient/mainwindow.cpp @@ -6,7 +6,7 @@ class MainWindowPrivate { public: - MainWindowPrivate(QWidget *owner) + explicit MainWindowPrivate(QWidget *owner) : owner(owner) { ipEdit = new QLineEdit(owner); diff --git a/MulClient/mainwindow.h b/MulClient/mainwindow.h index b4337fb..582318e 100644 --- a/MulClient/mainwindow.h +++ b/MulClient/mainwindow.h @@ -8,13 +8,13 @@ class MainWindow : public QMainWindow { Q_OBJECT public: - MainWindow(QWidget *parent = nullptr); - ~MainWindow(); + explicit MainWindow(QWidget *parent = nullptr); + ~MainWindow() override; private slots: void onConnect(bool); void onWrite(); - void removeOne(const int index); + void removeOne(int index); private: void warningBox(const QString&, QWidget*); diff --git a/MulClient/tcpclient.cpp b/MulClient/tcpclient.cpp index c47bc9e..669f1dc 100644 --- a/MulClient/tcpclient.cpp +++ b/MulClient/tcpclient.cpp @@ -13,7 +13,7 @@ TcpClient::~TcpClient() qDebug() << "~TcpClient"; } -QString TcpClient::getInfo() const +auto TcpClient::getInfo() const -> QString { QString info = peerName() + " " + peerAddress().toString() + " " + QString::number(peerPort()) + " "; diff --git a/MulClient/tcpclient.h b/MulClient/tcpclient.h index 7fc0488..acfb9ef 100644 --- a/MulClient/tcpclient.h +++ b/MulClient/tcpclient.h @@ -7,13 +7,13 @@ class TcpClient : public QTcpSocket { Q_OBJECT public: - TcpClient(QObject *parent = nullptr); - ~TcpClient(); + explicit TcpClient(QObject *parent = nullptr); + ~TcpClient() override; - QString getInfo() const; + [[nodiscard]] auto getInfo() const -> QString; public slots: - void onWrite(const QByteArray&); + void onWrite(const QByteArray &); void onReadyRead(); }; diff --git a/MulClient/tcpclientthread.cpp b/MulClient/tcpclientthread.cpp index 204ce0d..90eb23e 100644 --- a/MulClient/tcpclientthread.cpp +++ b/MulClient/tcpclientthread.cpp @@ -3,7 +3,7 @@ class TcpClientThreadPrivate{ public: - TcpClientThreadPrivate(QThread *parent = nullptr) + explicit TcpClientThreadPrivate(QThread *parent = nullptr) : owner(parent){} QThread *owner; QString ip = "127.0.0.1"; diff --git a/MulClient/tcpclientthread.h b/MulClient/tcpclientthread.h index 6606b4f..5948198 100644 --- a/MulClient/tcpclientthread.h +++ b/MulClient/tcpclientthread.h @@ -9,14 +9,14 @@ class TcpClientThread : public QThread Q_OBJECT public: TcpClientThread(const QString &ip, - const quint16 port, - const int index, + quint16 port, + int index, QObject *parent = nullptr); ~TcpClientThread() override; signals: void writeToServer(const QByteArray&); - void quitThread(const int); + void quitThread(int); private slots: void removeMyself(); diff --git a/MulServer/accepter.h b/MulServer/accepter.h index f893850..950e17c 100644 --- a/MulServer/accepter.h +++ b/MulServer/accepter.h @@ -7,7 +7,7 @@ class Accepter : public QThread { Q_OBJECT public: - Accepter(quint16, QObject *parent = nullptr); + explicit Accepter(quint16, QObject *parent = nullptr); ~Accepter() override; signals: diff --git a/MulServer/main.cpp b/MulServer/main.cpp index fd3e533..24ba3b6 100644 --- a/MulServer/main.cpp +++ b/MulServer/main.cpp @@ -2,7 +2,7 @@ #include -int main(int argc, char *argv[]) +auto main(int argc, char *argv[]) -> int { QApplication a(argc, argv); MainWindow w; diff --git a/MulServer/mainwindow.cpp b/MulServer/mainwindow.cpp index a9a4bcb..451f373 100644 --- a/MulServer/mainwindow.cpp +++ b/MulServer/mainwindow.cpp @@ -7,7 +7,7 @@ class MainWindowPrivate { public: - MainWindowPrivate(QMainWindow* owner) : owner(owner){ + explicit MainWindowPrivate(QMainWindow* owner) : owner(owner){ ipBox = new QComboBox(owner); portEdit = new QLineEdit(owner); listenBtn = new QPushButton(QObject::tr("Listen"), owner); diff --git a/MulServer/mainwindow.h b/MulServer/mainwindow.h index d526548..84f9a8c 100644 --- a/MulServer/mainwindow.h +++ b/MulServer/mainwindow.h @@ -9,8 +9,8 @@ class MainWindow : public QMainWindow Q_OBJECT public: - MainWindow(QWidget *parent = nullptr); - ~MainWindow(); + explicit MainWindow(QWidget *parent = nullptr); + ~MainWindow() override; private slots: void onListen(bool); diff --git a/MulServer/tcpclient.cpp b/MulServer/tcpclient.cpp index d8bb39d..e99a100 100644 --- a/MulServer/tcpclient.cpp +++ b/MulServer/tcpclient.cpp @@ -12,7 +12,7 @@ TcpClient::~TcpClient() qDebug() << "~TcpSocket"; } -QString TcpClient::getInfo() const +auto TcpClient::getInfo() const -> QString { QString info = peerName() + " " + peerAddress().toString() + " " + QString::number(peerPort()) + " "; diff --git a/MulServer/tcpclient.h b/MulServer/tcpclient.h index 1fe3fcb..f41c2de 100644 --- a/MulServer/tcpclient.h +++ b/MulServer/tcpclient.h @@ -7,10 +7,10 @@ class TcpClient : public QTcpSocket { Q_OBJECT public: - TcpClient(QObject *parent = nullptr); - ~TcpClient(); + explicit TcpClient(QObject *parent = nullptr); + ~TcpClient() override; - QString getInfo() const; + [[nodiscard]] auto getInfo() const -> QString; public slots: void onReadyRead(); diff --git a/MulServer/tcpserver.h b/MulServer/tcpserver.h index e4a66cc..638119c 100644 --- a/MulServer/tcpserver.h +++ b/MulServer/tcpserver.h @@ -7,7 +7,7 @@ class TcpServer : public QTcpServer { Q_OBJECT public: - TcpServer(QObject *parent = nullptr); + explicit TcpServer(QObject *parent = nullptr); ~TcpServer() override; signals: diff --git a/MulServer/thread.h b/MulServer/thread.h index e05b247..3bb330b 100644 --- a/MulServer/thread.h +++ b/MulServer/thread.h @@ -8,7 +8,7 @@ class Thread : public QThread { Q_OBJECT public: - Thread(qintptr socketDescriptor, QObject *parent = nullptr); + explicit Thread(qintptr socketDescriptor, QObject *parent = nullptr); ~Thread() override; signals: diff --git a/NavigationProgressBar/main.cpp b/NavigationProgressBar/main.cpp index fd3e533..24ba3b6 100644 --- a/NavigationProgressBar/main.cpp +++ b/NavigationProgressBar/main.cpp @@ -2,7 +2,7 @@ #include -int main(int argc, char *argv[]) +auto main(int argc, char *argv[]) -> int { QApplication a(argc, argv); MainWindow w; diff --git a/NavigationProgressBar/mainwindow.h b/NavigationProgressBar/mainwindow.h index d147190..b50d227 100644 --- a/NavigationProgressBar/mainwindow.h +++ b/NavigationProgressBar/mainwindow.h @@ -8,7 +8,7 @@ class MainWindow : public QMainWindow Q_OBJECT public: - MainWindow(QWidget *parent = nullptr); - ~MainWindow(); + explicit MainWindow(QWidget *parent = nullptr); + ~MainWindow() override; }; #endif // MAINWINDOW_H diff --git a/NavigationProgressBar/navigationprogressbar.cpp b/NavigationProgressBar/navigationprogressbar.cpp index fc1aa76..621403f 100644 --- a/NavigationProgressBar/navigationprogressbar.cpp +++ b/NavigationProgressBar/navigationprogressbar.cpp @@ -1,15 +1,17 @@ #include "navigationprogressbar.h" -#include #include #include +#include -class NavigationProgressBarPrivate{ +class NavigationProgressBarPrivate +{ public: - NavigationProgressBarPrivate(QWidget *parent) - : owner(parent){ - for(int i=0; i QSize { - return QSize(500, 100); + return {500, 100}; } -QSize NavigationProgressBar::minimumSizeHint() const +auto NavigationProgressBar::minimumSizeHint() const -> QSize { - return QSize(300, 75); + return {300, 75}; } void NavigationProgressBar::setMessageList(const QStringList &list) @@ -48,25 +47,26 @@ void NavigationProgressBar::setMessageList(const QStringList &list) update(); } -QStringList NavigationProgressBar::messageList() const +auto NavigationProgressBar::messageList() const -> QStringList { return d->topInfo; } void NavigationProgressBar::setStep(const int step) { - if(d->step >= step || step > d->maxStep) + if (d->step >= step || step > d->maxStep) { return; +} int s = step - d->step; - for(int i=0; idateList.append(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss")); d->step = step; Q_ASSERT(d->step == d->dateList.size()); update(); } -int NavigationProgressBar::step() const +auto NavigationProgressBar::step() const -> int { return d->step; } @@ -77,7 +77,7 @@ void NavigationProgressBar::setBackgroundColor(const QColor &color) update(); } -QColor NavigationProgressBar::backgroundColor() const +auto NavigationProgressBar::backgroundColor() const -> QColor { return d->backgroundColor; } @@ -88,7 +88,7 @@ void NavigationProgressBar::setCurrentBackgroundColor(const QColor &color) update(); } -QColor NavigationProgressBar::currentBackgroundColor() const +auto NavigationProgressBar::currentBackgroundColor() const -> QColor { return d->currentBackgroundColor; } @@ -99,7 +99,7 @@ void NavigationProgressBar::setForegroundColor(const QColor &color) update(); } -QColor NavigationProgressBar::foregroundColor() const +auto NavigationProgressBar::foregroundColor() const -> QColor { return d->foregroundColor; } @@ -131,7 +131,7 @@ void NavigationProgressBar::drawBackground(QPainter *painter, const bool ok) int step = d->maxStep; int penWidth = radius / 4; QColor backgroundColor = d->backgroundColor; - if(ok){ + if (ok) { step = d->step; penWidth = radius / 8; backgroundColor = d->currentBackgroundColor; @@ -149,8 +149,9 @@ void NavigationProgressBar::drawBackground(QPainter *painter, const bool ok) initX += w; } - if(ok && (d->step > 0) && (d->step < d->maxStep)) + if (ok && (d->step > 0) && (d->step < d->maxStep)) { painter->drawLine(QPoint(initX, initY), QPoint(initX + w / 2, initY)); +} //逐个绘制圆 initX = w / 2; @@ -183,19 +184,19 @@ void NavigationProgressBar::drawText(QPainter *painter, const bool ok) double initX = 0; double initY = 0; - QColor color = ok? d->currentBackgroundColor: d->backgroundColor; + QColor color = ok ? d->currentBackgroundColor : d->backgroundColor; painter->setFont(QFont("Microsoft YaHei", h / 4)); painter->setPen(color); painter->setBrush(Qt::NoBrush); - int step = ok ? d->step: d->maxStep; + int step = ok ? d->step : d->maxStep; for (int i = 0; i < step; i++) { QRect textRect(initX, initY, w, h); painter->drawText(textRect, Qt::AlignCenter, d->topInfo.at(i)); initX += w; } - if(ok){ + if (ok) { initX = 0; initY = h * 2; for (int i = 0; i < step; i++) { diff --git a/NavigationProgressBar/navigationprogressbar.h b/NavigationProgressBar/navigationprogressbar.h index cc20d34..95b8bed 100644 --- a/NavigationProgressBar/navigationprogressbar.h +++ b/NavigationProgressBar/navigationprogressbar.h @@ -15,25 +15,25 @@ class NavigationProgressBar : public QWidget Q_PROPERTY(QColor foregroundColor READ foregroundColor WRITE setForegroundColor) public: explicit NavigationProgressBar(QWidget *parent = nullptr); - ~NavigationProgressBar(); + ~NavigationProgressBar() override; - QSize sizeHint() const override; - QSize minimumSizeHint() const override; + [[nodiscard]] auto sizeHint() const -> QSize override; + [[nodiscard]] auto minimumSizeHint() const -> QSize override; void setMessageList(const QStringList &list); - QStringList messageList() const; + [[nodiscard]] auto messageList() const -> QStringList; void setStep(const int step); - int step() const; + [[nodiscard]] auto step() const -> int; void setBackgroundColor(const QColor &color); - QColor backgroundColor() const; + [[nodiscard]] auto backgroundColor() const -> QColor; void setCurrentBackgroundColor(const QColor &color); - QColor currentBackgroundColor() const; + [[nodiscard]] auto currentBackgroundColor() const -> QColor; void setForegroundColor(const QColor &color); - QColor foregroundColor() const; + [[nodiscard]] auto foregroundColor() const -> QColor; protected: void paintEvent(QPaintEvent *event) override; diff --git a/PasswordLineEdit/main.cc b/PasswordLineEdit/main.cc index e9bbf59..5d48a9d 100644 --- a/PasswordLineEdit/main.cc +++ b/PasswordLineEdit/main.cc @@ -7,7 +7,7 @@ #include #endif -int main(int argc, char *argv[]) +auto main(int argc, char *argv[]) -> int { QApplication a(argc, argv); MainWindow w; diff --git a/PasswordLineEdit/mainwindow.hpp b/PasswordLineEdit/mainwindow.hpp index ddd5081..121a60e 100644 --- a/PasswordLineEdit/mainwindow.hpp +++ b/PasswordLineEdit/mainwindow.hpp @@ -13,8 +13,8 @@ class MainWindow : public QMainWindow Q_OBJECT public: - MainWindow(QWidget *parent = nullptr); - ~MainWindow(); + explicit MainWindow(QWidget *parent = nullptr); + ~MainWindow() override; }; #endif // MAINWINDOW_HPP diff --git a/ProgressArc/main.cpp b/ProgressArc/main.cpp index fd3e533..24ba3b6 100644 --- a/ProgressArc/main.cpp +++ b/ProgressArc/main.cpp @@ -2,7 +2,7 @@ #include -int main(int argc, char *argv[]) +auto main(int argc, char *argv[]) -> int { QApplication a(argc, argv); MainWindow w; diff --git a/ProgressArc/mainwindow.h b/ProgressArc/mainwindow.h index d147190..b50d227 100644 --- a/ProgressArc/mainwindow.h +++ b/ProgressArc/mainwindow.h @@ -8,7 +8,7 @@ class MainWindow : public QMainWindow Q_OBJECT public: - MainWindow(QWidget *parent = nullptr); - ~MainWindow(); + explicit MainWindow(QWidget *parent = nullptr); + ~MainWindow() override; }; #endif // MAINWINDOW_H diff --git a/ProgressArc/progressarc.cpp b/ProgressArc/progressarc.cpp index 1f073a6..46bf40e 100644 --- a/ProgressArc/progressarc.cpp +++ b/ProgressArc/progressarc.cpp @@ -33,7 +33,7 @@ ProgressArc::ProgressArc(const QString &title, QWidget *parent) connect(this, &ProgressArc::valueChanged, this, &ProgressArc::onStartAnimation); } -ProgressArc::~ProgressArc() {} +ProgressArc::~ProgressArc() = default; void ProgressArc::setTitle(const QString &title) { @@ -41,7 +41,7 @@ void ProgressArc::setTitle(const QString &title) update(); } -QString ProgressArc::title() const +auto ProgressArc::title() const -> QString { return d_ptr->title; } @@ -52,7 +52,7 @@ void ProgressArc::setPercent(const bool percent) update(); } -bool ProgressArc::percent() const +auto ProgressArc::percent() const -> bool { return d_ptr->percent; } @@ -63,7 +63,7 @@ void ProgressArc::setMin(const double min) update(); } -double ProgressArc::min() const +auto ProgressArc::min() const -> double { return d_ptr->minValue; } @@ -74,7 +74,7 @@ void ProgressArc::setmax(const double max) update(); } -double ProgressArc::max() const +auto ProgressArc::max() const -> double { return d_ptr->maxValue; } @@ -85,7 +85,7 @@ void ProgressArc::setStartAngle(const double startAngle) update(); } -double ProgressArc::startAngle() const +auto ProgressArc::startAngle() const -> double { return d_ptr->startAngle; } @@ -96,7 +96,7 @@ void ProgressArc::setEndAngle(const double endAngle) update(); } -double ProgressArc::endAngle() const +auto ProgressArc::endAngle() const -> double { return d_ptr->endAngle; } @@ -107,7 +107,7 @@ void ProgressArc::setArcColor(const QColor &color) update(); } -QColor ProgressArc::arcColor() const +auto ProgressArc::arcColor() const -> QColor { return d_ptr->arcColor; } @@ -118,7 +118,7 @@ void ProgressArc::setTextColor(const QColor &color) update(); } -QColor ProgressArc::textColor() const +auto ProgressArc::textColor() const -> QColor { return d_ptr->textColor; } @@ -129,7 +129,7 @@ void ProgressArc::setTitleColor(const QColor &color) update(); } -QColor ProgressArc::titleColor() const +auto ProgressArc::titleColor() const -> QColor { return d_ptr->titleColor; } @@ -140,7 +140,7 @@ void ProgressArc::setBaseColor(const QColor &color) update(); } -QColor ProgressArc::baseColor() const +auto ProgressArc::baseColor() const -> QColor { return d_ptr->baseColor; } @@ -151,19 +151,19 @@ void ProgressArc::setBackgroundColor(const QColor &color) update(); } -QColor ProgressArc::backgroundColor() const +auto ProgressArc::backgroundColor() const -> QColor { return d_ptr->backgroundColor; } -QSize ProgressArc::sizeHint() const +auto ProgressArc::sizeHint() const -> QSize { - return QSize(200, 200); + return {200, 200}; } -QSize ProgressArc::minimumSizeHint() const +auto ProgressArc::minimumSizeHint() const -> QSize { - return QSize(80, 80); + return {80, 80}; } void ProgressArc::paintEvent(QPaintEvent *event) @@ -190,8 +190,9 @@ void ProgressArc::paintEvent(QPaintEvent *event) void ProgressArc::onStartAnimation(const double value) { - if (value < d_ptr->minValue || value > d_ptr->maxValue || value == d_ptr->value) + if (value < d_ptr->minValue || value > d_ptr->maxValue || value == d_ptr->value) { return; +} int start = d_ptr->value; int end = value; @@ -201,7 +202,7 @@ void ProgressArc::onStartAnimation(const double value) d_ptr->animation->start(); } -double ProgressArc::value() const +auto ProgressArc::value() const -> double { return d_ptr->value; } diff --git a/ProgressArc/progressarc.h b/ProgressArc/progressarc.h index 321e3ba..30b8dc8 100644 --- a/ProgressArc/progressarc.h +++ b/ProgressArc/progressarc.h @@ -20,46 +20,46 @@ class ProgressArc : public QWidget Q_PROPERTY(QColor backgroundColor READ backgroundColor WRITE setBackgroundColor) public: explicit ProgressArc(const QString &title, QWidget *parent = nullptr); - ~ProgressArc(); + ~ProgressArc() override; - QSize sizeHint() const override; - QSize minimumSizeHint() const override; + [[nodiscard]] auto sizeHint() const -> QSize override; + [[nodiscard]] auto minimumSizeHint() const -> QSize override; - double value() const; + [[nodiscard]] auto value() const -> double; void setValue(const double value); void setTitle(const QString &title); - QString title() const; + [[nodiscard]] auto title() const -> QString; void setPercent(const bool percent); - bool percent() const; + [[nodiscard]] auto percent() const -> bool; void setMin(const double min); - double min() const; + [[nodiscard]] auto min() const -> double; void setmax(const double max); - double max() const; + [[nodiscard]] auto max() const -> double; void setStartAngle(const double startAngle); - double startAngle() const; + [[nodiscard]] auto startAngle() const -> double; void setEndAngle(const double endAngle); - double endAngle() const; + [[nodiscard]] auto endAngle() const -> double; void setArcColor(const QColor &color); - QColor arcColor() const; + [[nodiscard]] auto arcColor() const -> QColor; void setTextColor(const QColor &color); - QColor textColor() const; + [[nodiscard]] auto textColor() const -> QColor; void setTitleColor(const QColor &color); - QColor titleColor() const; + [[nodiscard]] auto titleColor() const -> QColor; void setBaseColor(const QColor &color); - QColor baseColor() const; + [[nodiscard]] auto baseColor() const -> QColor; void setBackgroundColor(const QColor &color); - QColor backgroundColor() const; + [[nodiscard]] auto backgroundColor() const -> QColor; signals: void valueChanged(const double value); diff --git a/ProgressBar/main.cc b/ProgressBar/main.cc index e9bbf59..5d48a9d 100644 --- a/ProgressBar/main.cc +++ b/ProgressBar/main.cc @@ -7,7 +7,7 @@ #include #endif -int main(int argc, char *argv[]) +auto main(int argc, char *argv[]) -> int { QApplication a(argc, argv); MainWindow w; diff --git a/ProgressBar/mainwindow.hpp b/ProgressBar/mainwindow.hpp index fbb650e..695b56b 100644 --- a/ProgressBar/mainwindow.hpp +++ b/ProgressBar/mainwindow.hpp @@ -13,7 +13,7 @@ class MainWindow : public QMainWindow Q_OBJECT public: - MainWindow(QWidget *parent = nullptr); - ~MainWindow(); + explicit MainWindow(QWidget *parent = nullptr); + ~MainWindow() override; }; #endif // MAINWINDOW_HPP diff --git a/ProgressBar/progressbar.cc b/ProgressBar/progressbar.cc index 4960b5b..48f0dbd 100644 --- a/ProgressBar/progressbar.cc +++ b/ProgressBar/progressbar.cc @@ -30,16 +30,16 @@ ProgressBar::ProgressBar(QWidget *parent) connect(this, &ProgressBar::valueChanged, this, &ProgressBar::onStartAnimation); } -ProgressBar::~ProgressBar() {} +ProgressBar::~ProgressBar() = default; -QSize ProgressBar::sizeHint() const +auto ProgressBar::sizeHint() const -> QSize { - return QSize(165, 15); + return {165, 15}; } -QSize ProgressBar::minimumSizeHint() const +auto ProgressBar::minimumSizeHint() const -> QSize { - return QSize(100, 15); + return {100, 15}; } void ProgressBar::setValue(const double value) @@ -48,7 +48,7 @@ void ProgressBar::setValue(const double value) update(); } -double ProgressBar::value() const +auto ProgressBar::value() const -> double { return d_ptr->value; } @@ -59,7 +59,7 @@ void ProgressBar::setPercent(const bool percent) update(); } -bool ProgressBar::percent() const +auto ProgressBar::percent() const -> bool { return d_ptr->percent; } @@ -70,7 +70,7 @@ void ProgressBar::setMin(const double min) update(); } -double ProgressBar::min() const +auto ProgressBar::min() const -> double { return d_ptr->minValue; } @@ -81,7 +81,7 @@ void ProgressBar::setmax(const double max) update(); } -double ProgressBar::max() const +auto ProgressBar::max() const -> double { return d_ptr->maxValue; } @@ -92,7 +92,7 @@ void ProgressBar::setRadius(const double radius) update(); } -double ProgressBar::radius() const +auto ProgressBar::radius() const -> double { return d_ptr->radius; } @@ -103,7 +103,7 @@ void ProgressBar::setAutoRadius(bool autoRadius) update(); } -double ProgressBar::autoRadius() const +auto ProgressBar::autoRadius() const -> double { return d_ptr->autoRadius; } @@ -114,7 +114,7 @@ void ProgressBar::setChunkColor(const QColor &color) update(); } -QColor ProgressBar::chunkColor() const +auto ProgressBar::chunkColor() const -> QColor { return d_ptr->chunkColor; } @@ -125,7 +125,7 @@ void ProgressBar::setTextColor(const QColor &color) update(); } -QColor ProgressBar::textColor() const +auto ProgressBar::textColor() const -> QColor { return d_ptr->textColor; } @@ -136,7 +136,7 @@ void ProgressBar::setBaseColor(const QColor &color) update(); } -QColor ProgressBar::baseColor() const +auto ProgressBar::baseColor() const -> QColor { return d_ptr->baseColor; } @@ -147,15 +147,16 @@ void ProgressBar::setBackgroundColor(const QColor &color) update(); } -QColor ProgressBar::backgroundColor() const +auto ProgressBar::backgroundColor() const -> QColor { return d_ptr->backgroundColor; } void ProgressBar::onStartAnimation(const double value) { - if (value < d_ptr->minValue || value > d_ptr->maxValue || value == d_ptr->value) + if (value < d_ptr->minValue || value > d_ptr->maxValue || value == d_ptr->value) { return; +} int start = d_ptr->value; int end = value; diff --git a/ProgressBar/progressbar.hpp b/ProgressBar/progressbar.hpp index 847ab48..50c43f9 100644 --- a/ProgressBar/progressbar.hpp +++ b/ProgressBar/progressbar.hpp @@ -23,40 +23,40 @@ class ProgressBar : public QWidget Q_PROPERTY(QColor backgroundColor READ backgroundColor WRITE setBackgroundColor) public: explicit ProgressBar(QWidget *parent = nullptr); - ~ProgressBar(); + ~ProgressBar() override; - QSize sizeHint() const override; - QSize minimumSizeHint() const override; + [[nodiscard]] auto sizeHint() const -> QSize override; + [[nodiscard]] auto minimumSizeHint() const -> QSize override; void setValue(const double value); - double value() const; + [[nodiscard]] auto value() const -> double; void setPercent(const bool percent); - bool percent() const; + [[nodiscard]] auto percent() const -> bool; void setMin(const double min); - double min() const; + [[nodiscard]] auto min() const -> double; void setmax(const double max); - double max() const; + [[nodiscard]] auto max() const -> double; void setRadius(const double radius); - double radius() const; + [[nodiscard]] auto radius() const -> double; void setAutoRadius(bool autoRadius); - double autoRadius() const; + [[nodiscard]] auto autoRadius() const -> double; void setChunkColor(const QColor &color); - QColor chunkColor() const; + [[nodiscard]] auto chunkColor() const -> QColor; void setTextColor(const QColor &color); - QColor textColor() const; + [[nodiscard]] auto textColor() const -> QColor; void setBaseColor(const QColor &color); - QColor baseColor() const; + [[nodiscard]] auto baseColor() const -> QColor; void setBackgroundColor(const QColor &color); - QColor backgroundColor() const; + [[nodiscard]] auto backgroundColor() const -> QColor; signals: void valueChanged(const double value); diff --git a/README.md b/README.md index 11e93e1..32b6266 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ - [简体中文](README.md) - [English](README.en.md) -## 1. [Battery](Battery/)——电池; +## [Battery](Battery/)——电池; @@ -12,40 +12,40 @@
-## 2. [BubbleWindow](BubbleWindow/)——气泡式对话框,也可作工具提示(ToolTip); +## [BubbleWindow](BubbleWindow/)——气泡式对话框,也可作工具提示(ToolTip);
-## 3. [Chart](Chart/)——可视化图表绘制,参考[ 使用 QChart 显示实时动态曲线 ](https://qtdebug.com/qtbook-paint-realtime-curve-qchart/ "qtdebug/公孙二狗") 和QChart相关示例; +## [Chart](Chart/)——可视化图表绘制,参考[ 使用 QChart 显示实时动态曲线 ](https://qtdebug.com/qtbook-paint-realtime-curve-qchart/ "qtdebug/公孙二狗") 和QChart相关示例;
图一二是动态曲线
图一二是动态曲线, 图二坐标轴也会动态变化
-## 4. [CheckBoxStandardItem](/CheckBoxStandardItem)——可勾选StandardItem; +## [CheckBoxStandardItem](/CheckBoxStandardItem)——可以勾选的StandardItem,而且根据勾选状态自动更新父节点状态或者子节点状态;
-## 5. [Clock](/Clock)——时钟; +## [Clock](/Clock)——时钟;
-## 6. [DashBoard](/DashBoard)——仪表盘; +## [DashBoard](/DashBoard)——仪表盘;
-## 7. [FlowLayout](FlowLayout/)——流式布局,来自QT示例Flow Layout Example; +## [FlowLayout](FlowLayout/)——流式布局,来自QT示例Flow Layout Example;
-## 8. [DragDrop](DragDrop/)——简单控件拖拽,参考QT示例Drag and Drop Puzzle Example; +## [DragDrop](DragDrop/)——简单控件拖拽,参考QT示例Drag and Drop Puzzle Example; -## 9. [HttpClient ](/HttpClient)——http客户端; +## [HttpClient ](/HttpClient)——http客户端; -## 10. [GridViewModel ](/GridViewModel)——基于QListView的自适应宫图; +## [GridViewModel ](/GridViewModel)——基于QListView的自适应宫图;
-## 11. [LogAsynchronous](LogAsynchronous/)——异步日志,开辟一个线程专门往文件里写日志,前后端分离。 +## [LogAsynchronous](LogAsynchronous/)——异步日志,开辟一个线程专门往文件里写日志,前后端分离。 1. 日志文件名:应用程序名(appname).时间(time,精确到秒).主机hostname.进程ID(Tid).log(.count),假如一天内写的单个日志大约接近1G,会自动加后缀(.1,.2.3...,以此类推)新建新的日志文件去写,每天0点依然会rollFile; 1. 正常文件名:LogAsynchronous.2020-04-26-20-29-03.Youth.11828.log; @@ -53,15 +53,15 @@ 2. 日志格式:时间(time,精确到毫秒).线程ID(Pid).日志级别(debug).打印信息(msg).文件(File).行号(Line)。 1. 比如:2020-04-26 20:38:55.818 2052 [Debug] 123456789qwertyuioplkjhgfdsa 8412789-File:(..\logAsynchronous\main.cpp) Line:(19); -## 12. [MulClient](MulClient/)——多线程客户端,一个线程一个客户端(怎么可以绕开系统限制,模拟百万个客户端); +## [MulClient](MulClient/)——多线程客户端,一个线程一个客户端(怎么可以绕开系统限制,模拟百万个客户端); -## 13. [MulServer](MulServer/)——多线程服务端,一个线程一个客户端处理(处理实时性很高的TCP通讯); +## [MulServer](MulServer/)——多线程服务端,一个线程一个客户端处理(处理实时性很高的TCP通讯); -## 14. [NavigationProgressBar](/NavigationProgressBar)——导航进度栏; +## [NavigationProgressBar](/NavigationProgressBar)——导航进度栏;
-## 15. [PasswordLineEdit](PasswordLineEdit/)——密码输入框; +## [PasswordLineEdit](PasswordLineEdit/)——密码输入框; @@ -70,21 +70,21 @@
-## 16. [ProgressArc](ProgressArc/)——圆弧进度条; +## [ProgressArc](ProgressArc/)——圆弧进度条;
-## 17. [ProgressBar](ProgressBar)——QProgressBar圆角替代方案; +## [ProgressBar](ProgressBar)——QProgressBar圆角替代方案;
-## 18. [ReactorServer](ReactorServer/)——多线程服务端,Reactor模式(Echo); +## [ReactorServer](ReactorServer/)——多线程服务端,Reactor模式(Echo); -## 19. [SimpleUdp](SimpleUdp/)——简单UDP例子,广播和接收; +## [SimpleUdp](SimpleUdp/)——简单UDP例子,广播和接收; 防火墙白名单。 -## 20. [SlipButton](SlipButton/)——滑动按钮; +## [SlipButton](SlipButton/)——滑动按钮; 另:更简单的实现:[有动画效果的 CheckBox](http://qtdebug.com/qtbook-animated-checkbox/); @@ -95,24 +95,30 @@ -## 21. [SqlTabview](SqlTabview/)——SQLite数据库调用,模型方法; +## [SqlTabview](SqlTabview/)——SQLite数据库调用,模型方法; -## 22. [TableViewModel](TableViewModel/)——表格视图,DeleGate(Button and ProgressBar)(MVC); +## [TableViewModel](TableViewModel/)——表格视图; - 套用了旧的样式(懒),具体可以自己调整; +1. 各种自定义代理 + 1. [ButtonDelegate](./TableViewModel/buttondelegate.h); + 2. [ComboBoxDelegate](./TableViewModel/comboboxdelegate.h); + 3. [ProgressBarDelegate](./TableViewModel/progressbardelegate.h); + 4. [RichTextItemDelegate](./TableViewModel/richtextitemdelegate.hpp); + 5. [StarDelegate](./TableViewModel/stardelegate.h)----来自Qt示例Star Delegate Example; +2. 十万级数据渲染; -
+
-## 23. [Thread](Thread/)——多线程例子,6种写法; +## [Thread](Thread/)——多线程例子,6种写法; -## 24. [TreeViewModel](TreeViewModel/)——树形视图(MVC),QtCreator源码; +## [TreeViewModel](TreeViewModel/)——树形视图(MVC),QtCreator源码;
-## 25. [Validator](Validator/)——加强版IntValidator(QIntValidator)和DoubleValidator(QDoubleValidator) +## [Validator](Validator/)——加强版IntValidator(QIntValidator)和DoubleValidator(QDoubleValidator) -## 26. [Scripts](Scripts/)——打包脚本 +## [Scripts](Scripts/)——打包脚本 1. [macos](Scripts/macos/)——macos 通用编译打dmg包脚本(`python`/`dmgbuild`); 2. [widnows](Scripts/windows)——windows 通用编译打包安装脚本(Innosetup); diff --git a/ReactorServer/main.cpp b/ReactorServer/main.cpp index fd3e533..24ba3b6 100644 --- a/ReactorServer/main.cpp +++ b/ReactorServer/main.cpp @@ -2,7 +2,7 @@ #include -int main(int argc, char *argv[]) +auto main(int argc, char *argv[]) -> int { QApplication a(argc, argv); MainWindow w; diff --git a/ReactorServer/mainwindow.cpp b/ReactorServer/mainwindow.cpp index 73b64e4..445928d 100644 --- a/ReactorServer/mainwindow.cpp +++ b/ReactorServer/mainwindow.cpp @@ -7,7 +7,7 @@ class MainWindowPrivate { public: - MainWindowPrivate(QMainWindow* owner) : owner(owner){ + explicit MainWindowPrivate(QMainWindow* owner) : owner(owner){ ipBox = new QComboBox(owner); portEdit = new QLineEdit(owner); threadSpinBox = new QSpinBox(owner); diff --git a/ReactorServer/mainwindow.h b/ReactorServer/mainwindow.h index d526548..84f9a8c 100644 --- a/ReactorServer/mainwindow.h +++ b/ReactorServer/mainwindow.h @@ -9,8 +9,8 @@ class MainWindow : public QMainWindow Q_OBJECT public: - MainWindow(QWidget *parent = nullptr); - ~MainWindow(); + explicit MainWindow(QWidget *parent = nullptr); + ~MainWindow() override; private slots: void onListen(bool); diff --git a/ReactorServer/subreactor.h b/ReactorServer/subreactor.h index 8776d52..c4a9f44 100644 --- a/ReactorServer/subreactor.h +++ b/ReactorServer/subreactor.h @@ -7,8 +7,8 @@ class SubReactor : public QObject { Q_OBJECT public: - SubReactor(QObject *parent = nullptr); - ~SubReactor(); + explicit SubReactor(QObject *parent = nullptr); + ~SubReactor() override; signals: void message(const QString&); diff --git a/ReactorServer/tcpclient.cpp b/ReactorServer/tcpclient.cpp index d8bb39d..e99a100 100644 --- a/ReactorServer/tcpclient.cpp +++ b/ReactorServer/tcpclient.cpp @@ -12,7 +12,7 @@ TcpClient::~TcpClient() qDebug() << "~TcpSocket"; } -QString TcpClient::getInfo() const +auto TcpClient::getInfo() const -> QString { QString info = peerName() + " " + peerAddress().toString() + " " + QString::number(peerPort()) + " "; diff --git a/ReactorServer/tcpclient.h b/ReactorServer/tcpclient.h index 1fe3fcb..f41c2de 100644 --- a/ReactorServer/tcpclient.h +++ b/ReactorServer/tcpclient.h @@ -7,10 +7,10 @@ class TcpClient : public QTcpSocket { Q_OBJECT public: - TcpClient(QObject *parent = nullptr); - ~TcpClient(); + explicit TcpClient(QObject *parent = nullptr); + ~TcpClient() override; - QString getInfo() const; + [[nodiscard]] auto getInfo() const -> QString; public slots: void onReadyRead(); diff --git a/ReactorServer/tcpserver.cpp b/ReactorServer/tcpserver.cpp index 6a02013..b239624 100644 --- a/ReactorServer/tcpserver.cpp +++ b/ReactorServer/tcpserver.cpp @@ -1,23 +1,27 @@ #include "tcpserver.h" -#include "thread.h" #include "subreactor.h" +#include "thread.h" -class TcpServerPrivate{ +class TcpServerPrivate +{ public: - TcpServerPrivate(QObject *parent) : owner(parent) {} + explicit TcpServerPrivate(QObject *parent) + : owner(parent) + {} QObject *owner; - QVector threads; - SubReactor* subReactor = nullptr; + QVector threads; + SubReactor *subReactor = nullptr; int index = 0; }; -TcpServer::TcpServer(int num, QObject *parent) : QTcpServer(parent) - , d(new TcpServerPrivate(this)) +TcpServer::TcpServer(int num, QObject *parent) + : QTcpServer(parent) + , d(new TcpServerPrivate(this)) { qRegisterMetaType("qintptr"); qRegisterMetaType("QAtomicInt"); - for(int i=0; istart(); } - if(num <= 0){ // one Thread in Accepter + if (num <= 0) { // one Thread in Accepter d->subReactor = new SubReactor(this); connect(d->subReactor, &SubReactor::message, this, &TcpServer::message); connect(d->subReactor, &SubReactor::maxCount, this, &TcpServer::maxCount); @@ -36,7 +40,7 @@ TcpServer::TcpServer(int num, QObject *parent) : QTcpServer(parent) TcpServer::~TcpServer() { - if(!d->threads.isEmpty()){ + if (!d->threads.isEmpty()) { qDeleteAll(d->threads); d->threads.clear(); } @@ -49,20 +53,22 @@ TcpServer::~TcpServer() //------------------------------------------------- void TcpServer::incomingConnection(qintptr handle) { - Thread *thread = getNextThread(); - if(thread != nullptr) + auto thread = getNextThread(); + if (thread != nullptr) { emit thread->newConnectHandle(handle); - else if(d->subReactor != nullptr) + } else if (d->subReactor != nullptr) { d->subReactor->onNewConnect(handle); + } } -Thread *TcpServer::getNextThread() +auto TcpServer::getNextThread() -> Thread * { - if(d->threads.isEmpty()) + if (d->threads.isEmpty()) { return nullptr; - if(d->index < 0 || d->index >= d->threads.size()) + } + if (d->index < 0 || d->index >= d->threads.size()) d->index = 0; - Thread* thread = d->threads.at(d->index); + Thread *thread = d->threads.at(d->index); d->index++; return thread; } diff --git a/ReactorServer/tcpserver.h b/ReactorServer/tcpserver.h index ee80d94..786b4f6 100644 --- a/ReactorServer/tcpserver.h +++ b/ReactorServer/tcpserver.h @@ -10,7 +10,7 @@ class TcpServer : public QTcpServer { Q_OBJECT public: - TcpServer(int num = 10, QObject *parent = nullptr); + explicit TcpServer(int num = 10, QObject *parent = nullptr); ~TcpServer() override; signals: @@ -23,7 +23,7 @@ class TcpServer : public QTcpServer private: void createSocket(qintptr); - Thread* getNextThread(); + auto getNextThread() -> Thread*; QScopedPointer d; }; diff --git a/ReactorServer/thread.h b/ReactorServer/thread.h index e72239e..26e8f21 100644 --- a/ReactorServer/thread.h +++ b/ReactorServer/thread.h @@ -8,7 +8,7 @@ class Thread : public QThread { Q_OBJECT public: - Thread(QObject *parent = nullptr); + explicit Thread(QObject *parent = nullptr); ~Thread() override; signals: diff --git a/SlipButton/main.cpp b/SlipButton/main.cpp index fd3e533..24ba3b6 100644 --- a/SlipButton/main.cpp +++ b/SlipButton/main.cpp @@ -2,7 +2,7 @@ #include -int main(int argc, char *argv[]) +auto main(int argc, char *argv[]) -> int { QApplication a(argc, argv); MainWindow w; diff --git a/SlipButton/mainwindow.h b/SlipButton/mainwindow.h index d147190..b50d227 100644 --- a/SlipButton/mainwindow.h +++ b/SlipButton/mainwindow.h @@ -8,7 +8,7 @@ class MainWindow : public QMainWindow Q_OBJECT public: - MainWindow(QWidget *parent = nullptr); - ~MainWindow(); + explicit MainWindow(QWidget *parent = nullptr); + ~MainWindow() override; }; #endif // MAINWINDOW_H diff --git a/SlipButton/slipbutton.h b/SlipButton/slipbutton.h index 972f77d..448d556 100644 --- a/SlipButton/slipbutton.h +++ b/SlipButton/slipbutton.h @@ -8,36 +8,38 @@ class SlipButton : public QAbstractButton { Q_OBJECT Q_PROPERTY(int offset READ offset WRITE setOffset) - Q_PROPERTY(QColor checkedBackgroundColor READ checkedBackgroundColor WRITE setCheckedBackgroundColor) - Q_PROPERTY(QColor uncheckedBackgroundColor READ uncheckedBackgroundColor WRITE setUncheckedBackgroundColor) + Q_PROPERTY( + QColor checkedBackgroundColor READ checkedBackgroundColor WRITE setCheckedBackgroundColor) + Q_PROPERTY(QColor uncheckedBackgroundColor READ uncheckedBackgroundColor WRITE + setUncheckedBackgroundColor) public: - explicit SlipButton(QWidget* parent = nullptr); + explicit SlipButton(QWidget *parent = nullptr); ~SlipButton() override; - QSize sizeHint() const override; - QSize minimumSizeHint() const override; + [[nodiscard]] auto sizeHint() const -> QSize override; + [[nodiscard]] auto minimumSizeHint() const -> QSize override; public slots: void setCheckedBackgroundColor(const QColor &color); - QColor checkedBackgroundColor() const; + [[nodiscard]] auto checkedBackgroundColor() const -> QColor; void setUncheckedBackgroundColor(const QColor &color); - QColor uncheckedBackgroundColor() const; + [[nodiscard]] auto uncheckedBackgroundColor() const -> QColor; protected: - void paintEvent(QPaintEvent* event) override; + void paintEvent(QPaintEvent *event) override; void enterEvent(QEnterEvent *event) override; - void leaveEvent(QEvent* event) override; - void resizeEvent(QResizeEvent* event) override; + void leaveEvent(QEvent *event) override; + void resizeEvent(QResizeEvent *event) override; private slots: void onStartAnimation(); - int offset() const; + [[nodiscard]] auto offset() const -> int; void setOffset(int offset); private: - inline double widthMargin() const; - inline double heightMargin() const; + [[nodiscard]] inline auto widthMargin() const -> double; + [[nodiscard]] inline auto heightMargin() const -> double; QScopedPointer d; }; diff --git a/SqlTabview/main.cpp b/SqlTabview/main.cpp index fd3e533..24ba3b6 100644 --- a/SqlTabview/main.cpp +++ b/SqlTabview/main.cpp @@ -2,7 +2,7 @@ #include -int main(int argc, char *argv[]) +auto main(int argc, char *argv[]) -> int { QApplication a(argc, argv); MainWindow w; diff --git a/SqlTabview/mainwindow.cpp b/SqlTabview/mainwindow.cpp index 9b6267b..30b6efa 100644 --- a/SqlTabview/mainwindow.cpp +++ b/SqlTabview/mainwindow.cpp @@ -7,7 +7,7 @@ class MainWindowPrivate{ public: - MainWindowPrivate(QWidget *parent) + explicit MainWindowPrivate(QWidget *parent) :owner(parent){ sqlTabView = new QTableView(owner); sqlTabView->setAlternatingRowColors(true); diff --git a/SqlTabview/mainwindow.h b/SqlTabview/mainwindow.h index 9952b2f..4769884 100644 --- a/SqlTabview/mainwindow.h +++ b/SqlTabview/mainwindow.h @@ -10,8 +10,8 @@ class MainWindow : public QMainWindow Q_OBJECT public: - MainWindow(QWidget *parent = nullptr); - ~MainWindow(); + explicit MainWindow(QWidget *parent = nullptr); + ~MainWindow() override; private slots: void onAdd(); diff --git a/SqlTabview/sql.h b/SqlTabview/sql.h index 86b939a..e478d83 100644 --- a/SqlTabview/sql.h +++ b/SqlTabview/sql.h @@ -11,8 +11,8 @@ class Sql : public QObject public: explicit Sql(QObject *parent = nullptr); - static bool searchSQLite(QWidget* parent = nullptr); - QSqlError createOrOpenSqlite(); + static auto searchSQLite(QWidget* parent = nullptr) -> bool; + auto createOrOpenSqlite() -> QSqlError; signals: diff --git a/TableViewModel/CMakeLists.txt b/TableViewModel/CMakeLists.txt index 6edcae0..d677841 100644 --- a/TableViewModel/CMakeLists.txt +++ b/TableViewModel/CMakeLists.txt @@ -1,23 +1,29 @@ set(PROJECT_SOURCES - main.cpp - mainwindow.cpp - mainwindow.h - buttondelegate.h - buttondelegate.cpp - comboboxdelegate.h - comboboxdelegate.cpp - progressbardelegate.h - progressbardelegate.cpp - richtextitemdelegate.hpp - richtextitemdelegate.cc - sortfilterproxymodel.h - sortfilterproxymodel.cpp - student.h - studenttablemodel.h - studenttablemodel.cpp - stuedenttable.h - stuedenttable.cpp) + main.cpp + mainwindow.cpp + mainwindow.h + buttondelegate.h + buttondelegate.cpp + comboboxdelegate.h + comboboxdelegate.cpp + displaydata.hpp + displaytablemodel.hpp + displaytablemodel.cc + displaytableview.hpp + displaytableview.cc + progressbardelegate.h + progressbardelegate.cpp + richtextitemdelegate.hpp + richtextitemdelegate.cc + sortfilterproxymodel.h + sortfilterproxymodel.cpp + stardelegate.cpp + stardelegate.h + stareditor.cpp + stareditor.h + starrating.cpp + starrating.h) qt_add_executable(TableViewModel MANUAL_FINALIZATION ${PROJECT_SOURCES}) target_link_libraries(TableViewModel PRIVATE Qt6::Widgets) -qt_finalize_executable(TableViewModel) \ No newline at end of file +qt_finalize_executable(TableViewModel) diff --git a/TableViewModel/TableViewModel.pro b/TableViewModel/TableViewModel.pro index 7e5f253..7dd0f2c 100644 --- a/TableViewModel/TableViewModel.pro +++ b/TableViewModel/TableViewModel.pro @@ -18,24 +18,30 @@ DEFINES += QT_DEPRECATED_WARNINGS SOURCES += \ buttondelegate.cpp \ comboboxdelegate.cpp \ + displaytablemodel.cc \ + displaytableview.cc \ main.cpp \ mainwindow.cpp \ progressbardelegate.cpp \ richtextitemdelegate.cc \ sortfilterproxymodel.cpp \ - studenttablemodel.cpp \ - stuedenttable.cpp + stardelegate.cpp \ + stareditor.cpp \ + starrating.cpp HEADERS += \ buttondelegate.h \ comboboxdelegate.h \ + displaydata.hpp \ + displaytablemodel.hpp \ + displaytableview.hpp \ mainwindow.h \ progressbardelegate.h \ richtextitemdelegate.hpp \ sortfilterproxymodel.h \ - student.h \ - studenttablemodel.h \ - stuedenttable.h + stardelegate.h \ + stareditor.h \ + starrating.h # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin diff --git a/TableViewModel/buttondelegate.cpp b/TableViewModel/buttondelegate.cpp index 4127217..a222d30 100644 --- a/TableViewModel/buttondelegate.cpp +++ b/TableViewModel/buttondelegate.cpp @@ -1,17 +1,17 @@ #include "buttondelegate.h" -#include "student.h" +#include "displaydata.hpp" -#include #include #include +#include #include ButtonDelegate::ButtonDelegate(QObject *parent) : QStyledItemDelegate(parent) , m_buttonPtr(new QStyleOptionButton) -{ - -} +{} + +ButtonDelegate::~ButtonDelegate() {} void ButtonDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, @@ -43,32 +43,34 @@ bool ButtonDelegate::editorEvent(QEvent *event, int w = qMin(option.rect.width(), option.rect.height()) / 10.0; switch (event->type()) { - case QEvent::MouseButtonPress:{ - QMouseEvent* mouseEvent =(QMouseEvent*)event; + case QEvent::MouseButtonPress: { + QMouseEvent *mouseEvent = (QMouseEvent *) event; if (option.rect.adjusted(w, w, -w, -w).contains(mouseEvent->pos())) { m_buttonPtr->state |= QStyle::State_Sunken; } } break; - case QEvent::MouseButtonRelease:{ - QMouseEvent* mouseEvent =(QMouseEvent*)event; + case QEvent::MouseButtonRelease: { + QMouseEvent *mouseEvent = (QMouseEvent *) event; if (option.rect.adjusted(w, w, -w, -w).contains(mouseEvent->pos())) { m_buttonPtr->state &= (~QStyle::State_Sunken); - Student stu = model->data(index, Qt::UserRole).value(); - QString details = tr("This Student id = %1, name = %2, age = %3, " - "gender = %4, achievement = %5") - .arg(stu.id()) - .arg(stu.name()) - .arg(stu.age()) - .arg(stu.gender()) - .arg(stu.achievement()); - QDialog dialog; - QHBoxLayout *layout = new QHBoxLayout(&dialog); - layout->addWidget(new QLabel(details, &dialog)); - dialog.exec(); + auto data = model->data(index, Qt::UserRole).value(); + auto details = tr("Title: %1\nNumber: %2\nState: %3\nProcess: %4\nRichText: %5") + .arg(data.title()) + .arg(data.number()) + .arg(data.state()) + .arg(data.process()) + .arg(data.richText() + "x"); + + auto w = qobject_cast(model->parent()); + if (w) { + QDialog dialog(w); + QHBoxLayout *layout = new QHBoxLayout(&dialog); + layout->addWidget(new QLabel(details, &dialog)); + dialog.exec(); + } } - } - break; + } break; default: break; } return true; diff --git a/TableViewModel/buttondelegate.h b/TableViewModel/buttondelegate.h index fc0a030..f3a756a 100644 --- a/TableViewModel/buttondelegate.h +++ b/TableViewModel/buttondelegate.h @@ -6,16 +6,18 @@ class ButtonDelegate : public QStyledItemDelegate { public: - ButtonDelegate(QObject* parent = nullptr); + explicit ButtonDelegate(QObject *parent = nullptr); + ~ButtonDelegate() override; void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override; protected: - bool editorEvent(QEvent *event, QAbstractItemModel *model, + auto editorEvent(QEvent *event, + QAbstractItemModel *model, const QStyleOptionViewItem &option, - const QModelIndex &index) override; + const QModelIndex &index) -> bool override; private: QScopedPointer m_buttonPtr; diff --git a/TableViewModel/comboboxdelegate.cpp b/TableViewModel/comboboxdelegate.cpp index 6f0db2b..935f651 100644 --- a/TableViewModel/comboboxdelegate.cpp +++ b/TableViewModel/comboboxdelegate.cpp @@ -1,5 +1,4 @@ #include "comboboxdelegate.h" -#include "student.h" #include @@ -7,14 +6,16 @@ QWidget *ComboBoxDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &, const QModelIndex &) const { - QComboBox *comboBox = new QComboBox(parent); - comboBox->addItems(QStringList() << tr("MALE") << tr("FEMALE")); + static const QStringList items{tr("open"), tr("close")}; + + auto comboBox = new QComboBox(parent); + comboBox->addItems(items); return comboBox; } void ComboBoxDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const { - QComboBox *comboBox = qobject_cast(editor); + auto comboBox = qobject_cast(editor); comboBox->setCurrentIndex(index.data(Qt::EditRole).toInt()); } @@ -22,6 +23,6 @@ void ComboBoxDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const { - QComboBox *comboBox = qobject_cast(editor); + auto comboBox = qobject_cast(editor); model->setData(index, comboBox->currentText(), Qt::EditRole); } diff --git a/TableViewModel/comboboxdelegate.h b/TableViewModel/comboboxdelegate.h index 4ac4df4..5e6caa0 100644 --- a/TableViewModel/comboboxdelegate.h +++ b/TableViewModel/comboboxdelegate.h @@ -11,9 +11,9 @@ class ComboBoxDelegate : public QStyledItemDelegate : QStyledItemDelegate(parent) {} - QWidget *createEditor(QWidget *parent, + auto createEditor(QWidget *parent, const QStyleOptionViewItem &, - const QModelIndex &) const Q_DECL_OVERRIDE; + const QModelIndex &) const -> QWidget * Q_DECL_OVERRIDE; void setEditorData(QWidget *editor, const QModelIndex &index) const Q_DECL_OVERRIDE; void setModelData(QWidget *editor, QAbstractItemModel *model, diff --git a/TableViewModel/displaydata.hpp b/TableViewModel/displaydata.hpp new file mode 100644 index 0000000..2136d6a --- /dev/null +++ b/TableViewModel/displaydata.hpp @@ -0,0 +1,84 @@ +#pragma once + +#include + +class DisplayData : public QSharedData +{ +public: + DisplayData() = default; + DisplayData(const DisplayData &other) + : QSharedData(other) + , checked(other.checked) + , title(other.title) + , number(other.number) + , state(other.state) + , process(other.process) + , rating(other.rating) + , richText(other.richText) + {} + ~DisplayData() = default; + + bool checked = false; + QString title = QObject::tr("title"); + qint16 number = QRandomGenerator::global()->bounded(100); + QString state = QObject::tr("close"); + qint16 process = 50; + int rating = 3; + QString richText = QObject::tr("RichText"); +}; + +class DisplayInfo +{ +public: + DisplayInfo() + : d_ptr(new DisplayData) + {} + + DisplayInfo(bool checked, + const QString &title, + const qint16 number, + const QString &state, + qint16 process, + int rating, + const QString &richText) + : d_ptr(new DisplayData) + { + setChecked(checked); + setTitle(title); + setNumber(number); + setState(state); + setProcess(process); + setRating(rating); + setRichText(richText); + } + + DisplayInfo(const DisplayInfo &other) + : d_ptr(other.d_ptr) + {} + + void setChecked(bool checked) { d_ptr->checked = checked; } + [[nodiscard]] auto checked() const -> bool { return d_ptr->checked; } + + void setTitle(const QString &title) { d_ptr->title = title; } + [[nodiscard]] auto title() const -> QString { return d_ptr->title; } + + void setNumber(const qint16 number) { d_ptr->number = number; } + [[nodiscard]] auto number() const -> qint16 { return d_ptr->number; } + + void setState(const QString &state) { d_ptr->state = state; } + [[nodiscard]] auto state() const -> QString { return d_ptr->state; } + + void setProcess(qint16 process) { d_ptr->process = process; } + [[nodiscard]] auto process() const -> qint16 { return d_ptr->process; } + + void setRating(int rating) { d_ptr->rating = rating; } + [[nodiscard]] auto rating() const -> int { return d_ptr->rating; } + + void setRichText(const QString &richText) { d_ptr->richText = richText; } + [[nodiscard]] auto richText() const -> QString { return d_ptr->richText; } + +private: + QExplicitlySharedDataPointer d_ptr; +}; + +Q_DECLARE_METATYPE(DisplayInfo) diff --git a/TableViewModel/displaytablemodel.cc b/TableViewModel/displaytablemodel.cc new file mode 100644 index 0000000..5ec836b --- /dev/null +++ b/TableViewModel/displaytablemodel.cc @@ -0,0 +1,125 @@ +#include "displaytablemodel.hpp" +#include "starrating.h" + +#include +#include + +DisplayTableModel::DisplayTableModel(QObject *parent) + : QAbstractTableModel(parent) +{ + auto metaEnums = QMetaEnum::fromType(); + for (int i = 0; i < metaEnums.keyCount(); ++i) { + m_headerDatas << metaEnums.key(i); + } +} + +auto DisplayTableModel::data(const QModelIndex &index, int role) const -> QVariant +{ + if (!index.isValid()) { + return {}; + } + + auto row = index.row(); + auto col = index.column(); + + const auto &data = m_datas.at(row); + switch (role) { + case Qt::TextAlignmentRole: return Qt::AlignCenter; + case Qt::CheckStateRole: + if (ID == col) { + return data.checked() ? Qt::Checked : Qt::Unchecked; + } + break; + case Qt::DecorationRole: + if (ID == col) { + return qApp->style()->standardIcon(QStyle::SP_ComputerIcon); + } + break; + case Qt::WhatsThisRole: + case Qt::ToolTipRole: + case Qt::DisplayRole: + case Qt::EditRole: { //双击为空需添加 + switch (col) { + case ID: return row; + case TITLE: return data.title(); + case NUMBER: return data.number(); + case STATE: return data.state(); + case PROCESS: return data.process(); + case RICHTEXT: return data.richText(); + case DETAILS: return tr("Details"); + default: break; + } + break; + case Qt::UserRole: + if (col == RATING) { + return QVariant::fromValue(StarRating(data.rating())); + } + return QVariant::fromValue(data); + } + default: break; + } + return {}; +} + +auto DisplayTableModel::setData(const QModelIndex &index, const QVariant &value, int role) -> bool +{ + if (!index.isValid()) { + return false; + } + + auto row = index.row(); + auto col = index.column(); + + auto data = m_datas.at(row); + switch (role) { + case Qt::CheckStateRole: + if (ID == col) { + data.setChecked(value.toBool()); + } + break; + case Qt::EditRole: { + switch (col) { + case TITLE: data.setTitle(value.toString()); break; + case NUMBER: data.setNumber(value.toInt()); break; + case STATE: data.setState(value.toString()); break; + case PROCESS: data.setProcess(value.toInt()); break; + case RATING: data.setRating(value.value().starCount()); break; + case RICHTEXT: data.setRichText(value.toString()); break; + default: break; + } + } + default: break; + } + emit dataChanged(index, index); + return true; +} + +auto DisplayTableModel::headerData(int section, Qt::Orientation orientation, int role) const + -> QVariant +{ + if (section < 0 || section >= m_headerDatas.size() || orientation != Qt::Horizontal) { + return {}; + } + switch (role) { + case Qt::TextAlignmentRole: return Qt::AlignCenter; + case Qt::WhatsThisRole: + case Qt::ToolTipRole: + case Qt::DisplayRole: return m_headerDatas.at(section); + default: break; + } + return {}; +} + +Qt::ItemFlags DisplayTableModel::flags(const QModelIndex &index) const +{ + if (!index.isValid()) { + return {}; + } + auto flags = QAbstractTableModel::flags(index); + if (index.column() == ID) { + flags |= Qt::ItemIsUserCheckable; + } else { + flags |= Qt::ItemIsEditable; + } + return flags; +} diff --git a/TableViewModel/displaytablemodel.hpp b/TableViewModel/displaytablemodel.hpp new file mode 100644 index 0000000..1039b7e --- /dev/null +++ b/TableViewModel/displaytablemodel.hpp @@ -0,0 +1,42 @@ +#pragma once + +#include "displaydata.hpp" + +#include + +class DisplayTableModel : public QAbstractTableModel +{ + Q_OBJECT +public: + enum Property { ID, TITLE, NUMBER, STATE, PROCESS, RATING, DETAILS, RICHTEXT }; + Q_ENUM(Property); + + explicit DisplayTableModel(QObject *parent = nullptr); + + [[nodiscard]] auto rowCount(const QModelIndex & = QModelIndex()) const -> int + { + return m_datas.size(); + } + [[nodiscard]] auto columnCount(const QModelIndex & = QModelIndex()) const -> int + { + return m_headerDatas.size(); + } + + [[nodiscard]] auto data(const QModelIndex &index, int role = Qt::DisplayRole) const -> QVariant; + auto setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) -> bool; + [[nodiscard]] auto headerData(int section, + Qt::Orientation orientation, + int role = Qt::DisplayRole) const -> QVariant; + [[nodiscard]] auto flags(const QModelIndex &index) const -> Qt::ItemFlags; + + void setDatas(const QVector &datas) + { + beginResetModel(); + m_datas = datas; + endResetModel(); + } + +private: + QVector m_datas; + QStringList m_headerDatas; +}; diff --git a/TableViewModel/displaytableview.cc b/TableViewModel/displaytableview.cc new file mode 100644 index 0000000..2c77df9 --- /dev/null +++ b/TableViewModel/displaytableview.cc @@ -0,0 +1,79 @@ +#include "displaytableview.hpp" +#include "buttondelegate.h" +#include "comboboxdelegate.h" +#include "displaytablemodel.hpp" +#include "progressbardelegate.h" +#include "richtextitemdelegate.hpp" +#include "sortfilterproxymodel.h" +#include "stardelegate.h" + +#include +#include +#include + +class DisplayTableView::DisplayTableViewPrivate +{ +public: + explicit DisplayTableViewPrivate(DisplayTableView *parent) + : q_ptr(parent) + { + model = new DisplayTableModel(q_ptr); + + menu = new QMenu(q_ptr); + menu->addAction(QObject::tr("Insert"), q_ptr, &DisplayTableView::insertItem); + menu->addAction(QObject::tr("Remove"), q_ptr, &DisplayTableView::removeItem); + menu->addAction(QObject::tr("Rename"), q_ptr, [this] { + q_ptr->edit(q_ptr->currentIndex().siblingAtColumn(DisplayTableModel::TITLE)); + }); + } + + DisplayTableView *q_ptr; + + DisplayTableModel *model; + QMenu *menu; +}; + +DisplayTableView::DisplayTableView(QWidget *parent) + : QTableView(parent) + , d_ptr(new DisplayTableViewPrivate(this)) +{ + auto sortModel = new SortFilterProxyModel(this); + sortModel->setSourceModel(d_ptr->model); + setModel(sortModel); + + setShowGrid(true); + setWordWrap(false); + setAlternatingRowColors(true); + verticalHeader()->setVisible(false); + verticalHeader()->setDefaultSectionSize(35); + horizontalHeader()->setStretchLastSection(true); + horizontalHeader()->setDefaultSectionSize(120); + horizontalHeader()->setMinimumSectionSize(60); + horizontalHeader()->setSectionResizeMode(QHeaderView::Interactive); + setSelectionBehavior(QAbstractItemView::SelectRows); + setSelectionMode(QAbstractItemView::ExtendedSelection); + setContextMenuPolicy(Qt::DefaultContextMenu); + setSortingEnabled(true); + setIconSize(QSize(20, 20)); + + setItemDelegateForColumn(DisplayTableModel::STATE, new ComboBoxDelegate(this)); + setItemDelegateForColumn(DisplayTableModel::PROCESS, new ProgressBarDelegate(this)); + setItemDelegateForColumn(DisplayTableModel::RATING, new StarDelegate(this)); + setItemDelegateForColumn(DisplayTableModel::RICHTEXT, new RichTextItemDelegate(this)); + setItemDelegateForColumn(DisplayTableModel::DETAILS, new ButtonDelegate(this)); +} + +DisplayTableView::~DisplayTableView() = default; + +void DisplayTableView::setDatas(const QVector &datas) +{ + d_ptr->model->setDatas(datas); +} + +void DisplayTableView::contextMenuEvent(QContextMenuEvent *event) +{ + if (!currentIndex().isValid()) { + return; + } + d_ptr->menu->exec(mapToGlobal(event->pos())); +} diff --git a/TableViewModel/displaytableview.hpp b/TableViewModel/displaytableview.hpp new file mode 100644 index 0000000..830c506 --- /dev/null +++ b/TableViewModel/displaytableview.hpp @@ -0,0 +1,26 @@ +#pragma once + +#include "displaydata.hpp" + +#include + +class DisplayTableView : public QTableView +{ + Q_OBJECT +public: + explicit DisplayTableView(QWidget *parent = nullptr); + ~DisplayTableView() override; + + void setDatas(const QVector &datas); + +protected: + void contextMenuEvent(QContextMenuEvent *event) override; + +signals: + void insertItem(); + void removeItem(); + +private: + class DisplayTableViewPrivate; + QScopedPointer d_ptr; +}; diff --git a/TableViewModel/main.cpp b/TableViewModel/main.cpp index ea84d06..2be1a2d 100644 --- a/TableViewModel/main.cpp +++ b/TableViewModel/main.cpp @@ -1,22 +1,11 @@ #include "mainwindow.h" #include -#include -int main(int argc, char *argv[]) +auto main(int argc, char *argv[]) -> int { QApplication a(argc, argv); - // 套用了旧的样式,具体细节自己调整 - // const QString filePath("D:/Mine/CODE/Qt/Qt-App/resource/qss/base/Common.css"); - // if(QFile::exists(filePath)){ - // QFile file(filePath); - // if(file.open(QFile::ReadOnly)){ - // qApp->setStyleSheet(file.readAll()); - // file.close(); - // } - // } - MainWindow w; w.show(); diff --git a/TableViewModel/mainwindow.cpp b/TableViewModel/mainwindow.cpp index 0c80309..5617780 100644 --- a/TableViewModel/mainwindow.cpp +++ b/TableViewModel/mainwindow.cpp @@ -1,7 +1,5 @@ #include "mainwindow.h" -#include "student.h" -#include "studenttablemodel.h" -#include "stuedenttable.h" +#include "displaytableview.hpp" #include @@ -10,83 +8,96 @@ MainWindow::MainWindow(QWidget *parent) { setupUI(); init(); - resize(800, 300); + resize(1000, 618); } -MainWindow::~MainWindow() -{ -} +MainWindow::~MainWindow() = default; void MainWindow::onInsertItem() { int row = m_table->currentIndex().row(); - Student stu; - stu.setId(m_students.size()); - if (row < 0 || row >= m_students.size()) - m_students.append(stu); - else - m_students.insert(row, stu); + auto data = DisplayInfo{}; + if (row < 0 || row >= m_datas.size()) { + m_datas.append(data); + } else { + m_datas.insert(row, data); + } - m_table->setStudents(m_students); + m_table->setDatas(m_datas); } void MainWindow::onRemoveItem() { QModelIndex index = m_table->currentIndex(); - if (!index.isValid()) + if (!index.isValid()) { return; + } int row = index.row(); - m_students.takeAt(row); - m_table->setStudents(m_students); + m_datas.takeAt(row); + m_table->setDatas(m_datas); } void MainWindow::init() { - m_students.append(Student(true, - 0, - "Jason", - 15, - "MALE", - 66, - 10, - "RRichText1xxxxxxxxxxxxx")); - m_students.append(Student( - false, 1, "Lily", 13, "FEMALE", 85, 20, "RRichText2x")); - m_students.append(Student( - true, 2, "Odin", 16, "FEMALE", 76, 30, "RRichText3x")); - m_students.append(Student(false, - 3, - "Willion", - 12, - "MALE", - 89, - 40, - "RRichText4yyyyyyyyyyyy")); - m_students.append(Student( - true, 4, "Nieo", 14, "MALE", 77, 50, "RRichText5x")); - m_table->setStudents(m_students); - m_table->selectRow(m_students.size() - 1); + m_datas.append({true, + tr("Book"), + static_cast(QRandomGenerator::global()->bounded(100)), + tr("close"), + 50, + 3, + "RRichText1xxxxxxxxxxxxx"}); + m_datas.append( + {false, tr("Pen"), 100, tr("open"), 20, 2, "RRichText2x"}); + m_datas.append({true, + tr("Pencil"), + 200, + tr("close"), + 30, + 1, + "RRichText3x"}); + m_datas.append({false, + tr("Eraser"), + static_cast(QRandomGenerator::global()->bounded(100)), + tr("open"), + 40, + 4, + "RRichText4yyyyyyyyyyyy"}); + m_datas.append({true, + tr("Ruler"), + 500, + tr("close"), + 50, + 5, + "RRichText5x"}); + + while (m_datas.size() < 1000 * 100) { + m_datas.append(m_datas); + } + + m_table->setDatas(m_datas); + m_table->selectRow(m_datas.size() - 1); } void MainWindow::setupUI() { - QPushButton *addBtn = new QPushButton(tr("Add"), this); - QPushButton *removeBtn = new QPushButton(tr("Remove"), this); - m_table = new StudentsTable(this); - QHBoxLayout *hLayout = new QHBoxLayout; + auto addBtn = new QPushButton(tr("Add"), this); + auto removeBtn = new QPushButton(tr("Remove"), this); + m_table = new DisplayTableView(this); + + auto hLayout = new QHBoxLayout; hLayout->addStretch(1); hLayout->addWidget(addBtn); hLayout->addWidget(removeBtn); - QVBoxLayout *layout = new QVBoxLayout; + + auto widget = new QWidget(this); + auto layout = new QVBoxLayout(widget); layout->addLayout(hLayout); layout->addWidget(m_table); - QFrame *frame = new QFrame(this); - frame->setLayout(layout); - setCentralWidget(frame); + setCentralWidget(widget); - connect(m_table, &StudentsTable::insertItem, this, &MainWindow::onInsertItem); - connect(m_table, &StudentsTable::removeItem, this, &MainWindow::onRemoveItem); + connect(m_table, &DisplayTableView::insertItem, this, &MainWindow::onInsertItem); + connect(m_table, &DisplayTableView::removeItem, this, &MainWindow::onRemoveItem); connect(addBtn, &QPushButton::clicked, this, &MainWindow::onInsertItem); connect(removeBtn, &QPushButton::clicked, this, &MainWindow::onRemoveItem); } diff --git a/TableViewModel/mainwindow.h b/TableViewModel/mainwindow.h index fd63dfd..dabc321 100644 --- a/TableViewModel/mainwindow.h +++ b/TableViewModel/mainwindow.h @@ -3,15 +3,14 @@ #include -#include "student.h" +#include "displaydata.hpp" -class StudentsTable; +class DisplayTableView; class MainWindow : public QMainWindow { Q_OBJECT - public: - MainWindow(QWidget *parent = nullptr); + explicit MainWindow(QWidget *parent = nullptr); ~MainWindow(); private slots: @@ -21,7 +20,9 @@ private slots: private: void init(); void setupUI(); - StudentsTable *m_table; - QVector m_students; + + DisplayTableView *m_table; + QVector m_datas; }; + #endif // MAINWINDOW_H diff --git a/TableViewModel/picture/TabViewModelDelegate.jpg b/TableViewModel/picture/TabViewModelDelegate.jpg new file mode 100644 index 0000000000000000000000000000000000000000..0195bb717c4665745ff9d89fe18f21c2f5f0760a GIT binary patch literal 162549 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 z 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 literal 0 HcmV?d00001 diff --git a/TableViewModel/picture/TabViewModelDelegate.png b/TableViewModel/picture/TabViewModelDelegate.png deleted file mode 100644 index 8a6e9ff483ac73a78dcffbeac742f19708ea0754..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11233 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 m_progressBarPtr; diff --git a/TableViewModel/richtextitemdelegate.cc b/TableViewModel/richtextitemdelegate.cc index 46fed84..79dcc7c 100644 --- a/TableViewModel/richtextitemdelegate.cc +++ b/TableViewModel/richtextitemdelegate.cc @@ -6,10 +6,10 @@ #include #include -bool textElide(Qt::TextElideMode textElideMode, +auto textElide(Qt::TextElideMode textElideMode, const QFont &font, QTextDocument &doc, - const QRect &rect) + const QRect &rect) -> bool { QFontMetrics fm(font); int dotWidth = fm.horizontalAdvance("..."); @@ -124,8 +124,8 @@ void RichTextItemDelegate::paint(QPainter *painter, painter->restore(); } -QSize RichTextItemDelegate::sizeHint(const QStyleOptionViewItem &option, - const QModelIndex &index) const +auto RichTextItemDelegate::sizeHint(const QStyleOptionViewItem &option, + const QModelIndex &index) const -> QSize { QStyleOptionViewItem options = option; initStyleOption(&options, index); @@ -133,5 +133,5 @@ QSize RichTextItemDelegate::sizeHint(const QStyleOptionViewItem &option, QTextDocument doc; doc.setHtml(options.text); doc.setTextWidth(options.rect.width()); - return QSize(doc.idealWidth(), doc.size().height()); + return {static_cast(doc.idealWidth()), static_cast(doc.size().height())}; } diff --git a/TableViewModel/richtextitemdelegate.hpp b/TableViewModel/richtextitemdelegate.hpp index ae4a298..665a48f 100644 --- a/TableViewModel/richtextitemdelegate.hpp +++ b/TableViewModel/richtextitemdelegate.hpp @@ -12,7 +12,8 @@ class RichTextItemDelegate : public QStyledItemDelegate void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override; - QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override; + [[nodiscard]] auto sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const + -> QSize override; Qt::TextElideMode textElideMode = Qt::ElideRight; }; diff --git a/TableViewModel/sortfilterproxymodel.cpp b/TableViewModel/sortfilterproxymodel.cpp index 30265bf..e9b286b 100644 --- a/TableViewModel/sortfilterproxymodel.cpp +++ b/TableViewModel/sortfilterproxymodel.cpp @@ -2,7 +2,7 @@ #include -bool SortFilterProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const +auto SortFilterProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const -> bool { QVariant leftData = sourceModel()->data(left); QVariant rightData = sourceModel()->data(right); diff --git a/TableViewModel/sortfilterproxymodel.h b/TableViewModel/sortfilterproxymodel.h index 34736ba..8d3d71f 100644 --- a/TableViewModel/sortfilterproxymodel.h +++ b/TableViewModel/sortfilterproxymodel.h @@ -6,11 +6,13 @@ class SortFilterProxyModel : public QSortFilterProxyModel { public: - SortFilterProxyModel(QObject *parent = nullptr) - : QSortFilterProxyModel(parent) {} + explicit SortFilterProxyModel(QObject *parent = nullptr) + : QSortFilterProxyModel(parent) + {} protected: - bool lessThan(const QModelIndex &left, const QModelIndex &right) const override; + [[nodiscard]] auto lessThan(const QModelIndex &left, const QModelIndex &right) const + -> bool override; }; #endif // SORTFILTERPROXYMODEL_H diff --git a/TableViewModel/stardelegate.cpp b/TableViewModel/stardelegate.cpp new file mode 100644 index 0000000..f0a0047 --- /dev/null +++ b/TableViewModel/stardelegate.cpp @@ -0,0 +1,90 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#include + +#include "stardelegate.h" +#include "stareditor.h" +#include "starrating.h" + +//! [0] +void StarDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, + const QModelIndex &index) const +{ + if (index.data(Qt::UserRole).canConvert()) { + StarRating starRating = qvariant_cast(index.data(Qt::UserRole)); + + if (option.state & QStyle::State_Selected) + painter->fillRect(option.rect, option.palette.highlight()); + + starRating.paint(painter, option.rect, option.palette, + StarRating::EditMode::ReadOnly); + } else { + QStyledItemDelegate::paint(painter, option, index); + } +//! [0] +} + +//! [1] +QSize StarDelegate::sizeHint(const QStyleOptionViewItem &option, + const QModelIndex &index) const +{ + if (index.data(Qt::UserRole).canConvert()) { + StarRating starRating = qvariant_cast(index.data(Qt::UserRole)); + return starRating.sizeHint(); + } + return QStyledItemDelegate::sizeHint(option, index); +} +//! [1] + +//! [2] +QWidget *StarDelegate::createEditor(QWidget *parent, + const QStyleOptionViewItem &option, + const QModelIndex &index) const + +{ + if (index.data(Qt::UserRole).canConvert()) { + StarEditor *editor = new StarEditor(parent); + connect(editor, &StarEditor::editingFinished, + this, &StarDelegate::commitAndCloseEditor); + return editor; + } + return QStyledItemDelegate::createEditor(parent, option, index); +} +//! [2] + +//! [3] +void StarDelegate::setEditorData(QWidget *editor, + const QModelIndex &index) const +{ + if (index.data(Qt::UserRole).canConvert()) { + StarRating starRating = qvariant_cast(index.data(Qt::UserRole)); + StarEditor *starEditor = qobject_cast(editor); + starEditor->setStarRating(starRating); + } else { + QStyledItemDelegate::setEditorData(editor, index); + } +} +//! [3] + +//! [4] +void StarDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, + const QModelIndex &index) const +{ + if (index.data(Qt::UserRole).canConvert()) { + StarEditor *starEditor = qobject_cast(editor); + model->setData(index, QVariant::fromValue(starEditor->starRating())); + } else { + QStyledItemDelegate::setModelData(editor, model, index); + } +} +//! [4] + +//! [5] +void StarDelegate::commitAndCloseEditor() +{ + StarEditor *editor = qobject_cast(sender()); + emit commitData(editor); + emit closeEditor(editor); +} +//! [5] diff --git a/TableViewModel/stardelegate.h b/TableViewModel/stardelegate.h new file mode 100644 index 0000000..c5686dd --- /dev/null +++ b/TableViewModel/stardelegate.h @@ -0,0 +1,31 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#ifndef STARDELEGATE_H +#define STARDELEGATE_H + +#include + +//! [0] +class StarDelegate : public QStyledItemDelegate +{ + Q_OBJECT +public: + using QStyledItemDelegate::QStyledItemDelegate; + + void paint(QPainter *painter, const QStyleOptionViewItem &option, + const QModelIndex &index) const override; + QSize sizeHint(const QStyleOptionViewItem &option, + const QModelIndex &index) const override; + QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, + const QModelIndex &index) const override; + void setEditorData(QWidget *editor, const QModelIndex &index) const override; + void setModelData(QWidget *editor, QAbstractItemModel *model, + const QModelIndex &index) const override; + +private slots: + void commitAndCloseEditor(); +}; +//! [0] + +#endif diff --git a/TableViewModel/stareditor.cpp b/TableViewModel/stareditor.cpp new file mode 100644 index 0000000..8bd3c85 --- /dev/null +++ b/TableViewModel/stareditor.cpp @@ -0,0 +1,63 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#include "stareditor.h" +#include "starrating.h" + +#include + +//! [0] +StarEditor::StarEditor(QWidget *parent) + : QWidget(parent) +{ + setMouseTracking(true); + setAutoFillBackground(true); +} +//! [0] + +QSize StarEditor::sizeHint() const +{ + return myStarRating.sizeHint(); +} + +//! [1] +void StarEditor::paintEvent(QPaintEvent *) +{ + QPainter painter(this); + myStarRating.paint(&painter, rect(), palette(), + StarRating::EditMode::Editable); +} +//! [1] + +//! [2] +void StarEditor::mouseMoveEvent(QMouseEvent *event) +{ + const int star = starAtPosition(event->position().toPoint().x()); + + if (star != myStarRating.starCount() && star != -1) { + myStarRating.setStarCount(star); + update(); + } + QWidget::mouseMoveEvent(event); +} +//! [2] + +//! [3] +void StarEditor::mouseReleaseEvent(QMouseEvent *event) +{ + emit editingFinished(); + QWidget::mouseReleaseEvent(event); +} +//! [3] + +//! [4] +int StarEditor::starAtPosition(int x) const +{ + const int star = (x / (myStarRating.sizeHint().width() + / myStarRating.maxStarCount())) + 1; + if (star <= 0 || star > myStarRating.maxStarCount()) + return -1; + + return star; +} +//! [4] diff --git a/TableViewModel/stareditor.h b/TableViewModel/stareditor.h new file mode 100644 index 0000000..bb54190 --- /dev/null +++ b/TableViewModel/stareditor.h @@ -0,0 +1,39 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#ifndef STAREDITOR_H +#define STAREDITOR_H + +#include + +#include "starrating.h" + +//! [0] +class StarEditor : public QWidget +{ + Q_OBJECT +public: + StarEditor(QWidget *parent = nullptr); + + QSize sizeHint() const override; + void setStarRating(const StarRating &starRating) { + myStarRating = starRating; + } + StarRating starRating() { return myStarRating; } + +signals: + void editingFinished(); + +protected: + void paintEvent(QPaintEvent *event) override; + void mouseMoveEvent(QMouseEvent *event) override; + void mouseReleaseEvent(QMouseEvent *event) override; + +private: + int starAtPosition(int x) const; + + StarRating myStarRating; +}; +//! [0] + +#endif diff --git a/TableViewModel/starrating.cpp b/TableViewModel/starrating.cpp new file mode 100644 index 0000000..421dc6f --- /dev/null +++ b/TableViewModel/starrating.cpp @@ -0,0 +1,60 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#include "starrating.h" + +#include +#include + +constexpr int PaintingScaleFactor = 20; + +//! [0] +StarRating::StarRating(int starCount, int maxStarCount) + : myStarCount(starCount), + myMaxStarCount(maxStarCount) +{ + starPolygon << QPointF(1.0, 0.5); + for (int i = 1; i < 5; ++i) + starPolygon << QPointF(0.5 + 0.5 * std::cos(0.8 * i * 3.14), + 0.5 + 0.5 * std::sin(0.8 * i * 3.14)); + + diamondPolygon << QPointF(0.4, 0.5) << QPointF(0.5, 0.4) + << QPointF(0.6, 0.5) << QPointF(0.5, 0.6) + << QPointF(0.4, 0.5); +} +//! [0] + +//! [1] +QSize StarRating::sizeHint() const +{ + return PaintingScaleFactor * QSize(myMaxStarCount, 1); +} +//! [1] + +//! [2] +void StarRating::paint(QPainter *painter, const QRect &rect, + const QPalette &palette, EditMode mode) const +{ + painter->save(); + + painter->setRenderHint(QPainter::Antialiasing, true); + painter->setPen(Qt::NoPen); + painter->setBrush(mode == EditMode::Editable ? + palette.highlight() : + palette.windowText()); + + const int yOffset = (rect.height() - PaintingScaleFactor) / 2; + painter->translate(rect.x(), rect.y() + yOffset); + painter->scale(PaintingScaleFactor, PaintingScaleFactor); + + for (int i = 0; i < myMaxStarCount; ++i) { + if (i < myStarCount) + painter->drawPolygon(starPolygon, Qt::WindingFill); + else if (mode == EditMode::Editable) + painter->drawPolygon(diamondPolygon, Qt::WindingFill); + painter->translate(1.0, 0.0); + } + + painter->restore(); +} +//! [2] diff --git a/TableViewModel/starrating.h b/TableViewModel/starrating.h new file mode 100644 index 0000000..31054dd --- /dev/null +++ b/TableViewModel/starrating.h @@ -0,0 +1,39 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#ifndef STARRATING_H +#define STARRATING_H + +#include +#include +#include + +//! [0] +class StarRating +{ +public: + enum class EditMode { Editable, ReadOnly }; + + explicit StarRating(int starCount = 1, int maxStarCount = 5); + + void paint(QPainter *painter, const QRect &rect, + const QPalette &palette, EditMode mode) const; + QSize sizeHint() const; + int starCount() const { return myStarCount; } + int maxStarCount() const { return myMaxStarCount; } + void setStarCount(int starCount) { myStarCount = starCount; } + void setMaxStarCount(int maxStarCount) { myMaxStarCount = maxStarCount; } + +private: + QPolygonF starPolygon; + QPolygonF diamondPolygon; + int myStarCount; + int myMaxStarCount; +}; +//! [0] + +//! [1] +Q_DECLARE_METATYPE(StarRating) +//! [1] + +#endif diff --git a/TableViewModel/student.h b/TableViewModel/student.h deleted file mode 100644 index 05c25fd..0000000 --- a/TableViewModel/student.h +++ /dev/null @@ -1,91 +0,0 @@ -#ifndef STUDENT_H -#define STUDENT_H - -#include - -class StudentData : public QSharedData -{ -public: - StudentData() {} - StudentData(const StudentData &other) - : QSharedData(other) - , checked(other.checked) - , id(other.id) - , name(other.name) - , age(other.age) - , gender(other.gender) - , achievement(other.achievement) - , process(other.process) - {} - ~StudentData() {} - - bool checked = false; - quint16 id = 0; - QString name; - quint16 age = 0; - QString gender = QObject::tr("MALE"); - quint16 achievement = 0; - qint16 process = 50; - QString richText; -}; - -class Student -{ -public: - Student() - : d_ptr(new StudentData) - {} - Student(bool checked, - quint16 id, - const QString &name, - quint16 age, - const QString &gender, - quint16 achievement, - qint16 process, - const QString &richText) - : d_ptr(new StudentData) - { - setChecked(checked); - setId(id); - setName(name); - setAge(age); - setGender(gender); - setAchievement(achievement); - setProcess(process); - setRichText(richText); - } - Student(const Student &other) - : d_ptr(other.d_ptr) - {} - - void setChecked(bool checked) { d_ptr->checked = checked; } - bool checked() const { return d_ptr->checked; } - - void setId(quint16 id) { d_ptr->id = id; } - quint16 id() const { return d_ptr->id; } - - void setName(const QString &name) { d_ptr->name = name; } - QString name() const { return d_ptr->name; } - - void setAge(quint16 age) { d_ptr->age = age; } - quint16 age() const { return d_ptr->age; } - - void setGender(const QString &gender) { d_ptr->gender = gender; } - QString gender() const { return d_ptr->gender; } - - void setAchievement(quint16 achievement) { d_ptr->achievement = achievement; } - quint16 achievement() const { return d_ptr->achievement; } - - void setProcess(qint16 process) { d_ptr->process = process; } - qint16 process() const { return d_ptr->process; } - - void setRichText(const QString &richText) { d_ptr->richText = richText; } - QString richText() const { return d_ptr->richText; }; - -private: - QExplicitlySharedDataPointer d_ptr; -}; - -Q_DECLARE_METATYPE(Student) - -#endif // STUDENT_H diff --git a/TableViewModel/studenttablemodel.cpp b/TableViewModel/studenttablemodel.cpp deleted file mode 100644 index 9bd95e1..0000000 --- a/TableViewModel/studenttablemodel.cpp +++ /dev/null @@ -1,126 +0,0 @@ -#include "studenttablemodel.h" - -#include -#include - -enum Property { ID, NAME, AGE, GENDER, ACHIEVEMENT, MENUBUTTON, PROCESS, RICHTEXT }; - -QVariant StuedentTableModel::data(const QModelIndex &index, int role) const -{ - if (!index.isValid()) - return false; - - int row = index.row(); - int col = index.column(); - - Student stu = m_students.at(row); - switch (role) { - case Qt::TextAlignmentRole: return Qt::AlignCenter; - case Qt::CheckStateRole: - if (ID == col) { - return stu.checked() ? Qt::Checked : Qt::Unchecked; - } - break; - case Qt::DecorationRole: - if (ID == col) { - return qApp->style()->standardIcon(QStyle::SP_ComputerIcon); - } - break; - case Qt::WhatsThisRole: - case Qt::ToolTipRole: - case Qt::DisplayRole: - case Qt::EditRole: { //双击为空需添加 - switch (col) { - case ID: return stu.id(); - case NAME: return stu.name(); - case AGE: return stu.age(); - case GENDER: return stu.gender(); - case ACHIEVEMENT: return stu.achievement(); - case MENUBUTTON: return tr("Detail"); - case PROCESS: return stu.process(); - case RICHTEXT: return stu.richText(); - default: break; - } - case Qt::UserRole: return QVariant::fromValue(stu); - } - default: break; - } - return QVariant(); -} - -bool StuedentTableModel::setData(const QModelIndex &index, const QVariant &value, int role) -{ - if (!index.isValid()) - return false; - - int row = index.row(); - int col = index.column(); - - Student stu = m_students.at(row); - switch (role) { - case Qt::CheckStateRole: - if (ID == col) { - stu.setChecked(value.toInt()); - emit dataChanged(index, index); - return true; - } - break; - case Qt::EditRole: - switch (col) { - case ID: stu.setId(value.toUInt()); break; - case NAME: stu.setName(value.toString()); break; - case AGE: stu.setAge(value.toUInt()); break; - case GENDER: stu.setGender(value.toString()); break; - case ACHIEVEMENT: stu.setAchievement(value.toUInt()); break; - case PROCESS: stu.setProcess(value.toUInt()); break; - case RICHTEXT: stu.setRichText(value.toString()); break; - } - emit dataChanged(index, index); - return true; - default: break; - } - return false; -} - -QVariant StuedentTableModel::headerData(int section, Qt::Orientation orientation, int role) const -{ - const QStringList names = {tr("ID"), - tr("NAME"), - tr("AGE"), - tr("GENDER"), - tr("ACHIEVEMENT"), - tr("DETAILS"), - tr("PROCESS"), - tr("RICHTEXT")}; - if (section < 0 || section >= names.size()) { - return QVariant(); - } - if (orientation == Qt::Horizontal) { - switch (role) { - case Qt::TextAlignmentRole: return Qt::AlignCenter; - case Qt::WhatsThisRole: - case Qt::ToolTipRole: - case Qt::DisplayRole: return names.at(section); - default: break; - } - } - - return QVariant(); -} - -Qt::ItemFlags StuedentTableModel::flags(const QModelIndex &index) const -{ - Qt::ItemFlags flags = QAbstractTableModel::flags(index); - flags |= Qt::ItemIsEditable; - if (index.column() == ID) { - flags |= Qt::ItemIsUserCheckable; - } - return flags; -} - -void StuedentTableModel::setStudents(const QVector &students) -{ - beginResetModel(); - m_students = students; - endResetModel(); -} diff --git a/TableViewModel/studenttablemodel.h b/TableViewModel/studenttablemodel.h deleted file mode 100644 index 2209a79..0000000 --- a/TableViewModel/studenttablemodel.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef STUDENTTABLEMODEL_H -#define STUDENTTABLEMODEL_H - -#include - -#include "student.h" - -class StuedentTableModel : public QAbstractTableModel -{ - Q_OBJECT -public: - explicit StuedentTableModel(QObject *parent = nullptr) - : QAbstractTableModel(parent) - {} - int rowCount(const QModelIndex & = QModelIndex()) const { return m_students.size(); } - int columnCount(const QModelIndex & = QModelIndex()) const { return 8; } - - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; - bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); - QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; - Qt::ItemFlags flags(const QModelIndex &index) const; - void setStudents(const QVector &students); - -private: - QVector m_students; -}; - -#endif // STUDENTTABLEMODEL_H diff --git a/TableViewModel/stuedenttable.cpp b/TableViewModel/stuedenttable.cpp deleted file mode 100644 index 72f421f..0000000 --- a/TableViewModel/stuedenttable.cpp +++ /dev/null @@ -1,60 +0,0 @@ -#include "stuedenttable.h" -#include "buttondelegate.h" -#include "comboboxdelegate.h" -#include "progressbardelegate.h" -#include "richtextitemdelegate.hpp" -#include "sortfilterproxymodel.h" -#include "studenttablemodel.h" - -#include - -StudentsTable::StudentsTable(QWidget *parent) - : QTableView(parent) - , m_stuModel(new StuedentTableModel(this)) - , m_menu(new QMenu(this)) -{ - SortFilterProxyModel *sortModel = new SortFilterProxyModel(this); - sortModel->setSourceModel(m_stuModel); - setModel(sortModel); - //setModel(m_stuModel); - - setShowGrid(true); - setWordWrap(false); - setAlternatingRowColors(true); - verticalHeader()->setVisible(false); - verticalHeader()->setDefaultSectionSize(30); - horizontalHeader()->setStretchLastSection(true); - horizontalHeader()->setDefaultSectionSize(90); - horizontalHeader()->setMinimumSectionSize(35); - horizontalHeader()->setSectionResizeMode(QHeaderView::Interactive); - setSelectionBehavior(QAbstractItemView::SelectRows); - setSelectionMode(QAbstractItemView::ExtendedSelection); - setContextMenuPolicy(Qt::DefaultContextMenu); - setItemDelegateForColumn(3, new ComboBoxDelegate(this)); - setItemDelegateForColumn(5, new ButtonDelegate(this)); - setItemDelegateForColumn(6, new ProgressBarDelegate(this)); - setItemDelegateForColumn(7, new RichTextItemDelegate(this)); - setSortingEnabled(true); - setIconSize(QSize(20, 20)); - - initMenu(); -} - -void StudentsTable::setStudents(const QVector &students) -{ - m_stuModel->setStudents(students); -} - -void StudentsTable::contextMenuEvent(QContextMenuEvent *event) -{ - if (!currentIndex().isValid()) - return; - m_menu->exec(mapToGlobal(event->pos())); -} - -void StudentsTable::initMenu() -{ - m_menu->addAction(tr("insert"), this, &StudentsTable::insertItem); - m_menu->addAction(tr("remove"), this, &StudentsTable::removeItem); - m_menu->addAction(tr("rename"), this, [this] { edit(currentIndex().siblingAtColumn(0)); }); -} diff --git a/TableViewModel/stuedenttable.h b/TableViewModel/stuedenttable.h deleted file mode 100644 index 7c088b2..0000000 --- a/TableViewModel/stuedenttable.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef STUDENTTABLE_H -#define STUDENTTABLE_H - -#include -#include -#include - -#include "student.h" - -class StuedentTableModel; -class StudentsTable : public QTableView -{ - Q_OBJECT -public: - StudentsTable(QWidget *parent = nullptr); - - void setStudents(const QVector &students); - -protected: - void contextMenuEvent(QContextMenuEvent *event) override; - -signals: - void insertItem(); - void removeItem(); - -private: - void initMenu(); - - StuedentTableModel *m_stuModel; - QMenu *m_menu; -}; - -#endif // STUDENTTABLE_H diff --git a/Thread/functions.hpp b/Thread/functions.hpp index 2478870..31e6ba6 100644 --- a/Thread/functions.hpp +++ b/Thread/functions.hpp @@ -5,7 +5,7 @@ namespace Functions { -QString getCurrentThreadIDStr(); +auto getCurrentThreadIDStr() -> QString; } diff --git a/Thread/main.cc b/Thread/main.cc index d550470..6c350c6 100644 --- a/Thread/main.cc +++ b/Thread/main.cc @@ -3,7 +3,7 @@ #include "thread.hpp" -int main(int argc, char *argv[]) +auto main(int argc, char *argv[]) -> int { QCoreApplication a(argc, argv); diff --git a/Thread/task.hpp b/Thread/task.hpp index 1a68a03..235e6ed 100644 --- a/Thread/task.hpp +++ b/Thread/task.hpp @@ -9,7 +9,7 @@ class Task : public QObject Q_OBJECT public: using QObject::QObject; - ~Task(); + ~Task() override; public slots: void onDo(const QString &text); diff --git a/Thread/thread.hpp b/Thread/thread.hpp index 20b9cf7..e24b85c 100644 --- a/Thread/thread.hpp +++ b/Thread/thread.hpp @@ -20,7 +20,7 @@ class Thread2 : public QThread Q_OBJECT public: using QThread::QThread; - ~Thread2(); + ~Thread2() override; public slots: void onDo(); @@ -36,8 +36,8 @@ class Thread3 : public QObject { Q_OBJECT public: - Thread3(QObject *parent = nullptr); - ~Thread3(); + explicit Thread3(QObject *parent = nullptr); + ~Thread3() override; void dooo(); @@ -53,6 +53,6 @@ void runThread4(); void runThread5(); -QThread *runThread6(); +auto runThread6() -> QThread *; #endif // THREAD_HPP diff --git a/TreeViewModel/checkboxheaderview.hpp b/TreeViewModel/checkboxheaderview.hpp index 4b8ddfd..d76a86a 100644 --- a/TreeViewModel/checkboxheaderview.hpp +++ b/TreeViewModel/checkboxheaderview.hpp @@ -9,7 +9,7 @@ class CheckBoxHeaderView : public QHeaderView public: explicit CheckBoxHeaderView(Qt::Orientation orientation = Qt::Horizontal, QWidget *parent = nullptr); - ~CheckBoxHeaderView(); + ~CheckBoxHeaderView() override; void setState(int state); diff --git a/TreeViewModel/fileinfo.cc b/TreeViewModel/fileinfo.cc index 601d9ce..5c3815f 100644 --- a/TreeViewModel/fileinfo.cc +++ b/TreeViewModel/fileinfo.cc @@ -1,6 +1,6 @@ #include "fileinfo.hpp" -QString bytesToString(qint64 bytes) +auto bytesToString(qint64 bytes) -> QString { static const double KB = 1024 * 1.0; static const double MB = KB * 1024; diff --git a/TreeViewModel/fileinfo.hpp b/TreeViewModel/fileinfo.hpp index 73aca4b..5eb1739 100644 --- a/TreeViewModel/fileinfo.hpp +++ b/TreeViewModel/fileinfo.hpp @@ -5,12 +5,12 @@ #include #include -QString bytesToString(qint64 bytes); +auto bytesToString(qint64 bytes) -> QString; class FileInfoData : public QSharedData { public: - FileInfoData() {} + FileInfoData() = default; FileInfoData(const FileInfoData &other) : QSharedData(other) , fileInfo(other.fileInfo) @@ -37,7 +37,7 @@ class FileInfo : d_ptr(new FileInfoData) {} - FileInfo(const QFileInfo &fileInfo) + explicit FileInfo(const QFileInfo &fileInfo) : d_ptr(new FileInfoData) { setFileInfo(fileInfo); @@ -53,31 +53,31 @@ class FileInfo : d_ptr(other.d_ptr) {} - ~FileInfo() {} + ~FileInfo() = default; - bool operator==(const FileInfo &other) const + auto operator==(const FileInfo &other) const -> bool { return d_ptr->fileInfo == other.d_ptr->fileInfo; } - bool operator!=(const FileInfo &other) const { return !(*this == other); } + auto operator!=(const FileInfo &other) const -> bool { return !(*this == other); } void setFileInfo(const QFileInfo &fileInfo) { d_ptr->fileInfo = fileInfo; } - QFileInfo fileInfo() const { return d_ptr->fileInfo; } + [[nodiscard]] QFileInfo fileInfo() const { return d_ptr->fileInfo; } void setIcon(const QIcon &icon) { d_ptr->icon = icon; } - QIcon icon() const { return d_ptr->icon; } + [[nodiscard]] QIcon icon() const { return d_ptr->icon; } void setType(const QString &type) { d_ptr->type = type; } - QString type() const { return d_ptr->type; } + [[nodiscard]] auto type() const -> QString { return d_ptr->type; } void setModifyTime(const QString &modifyTime) { d_ptr->modifyTime = modifyTime; } - QString modifyTime() const { return d_ptr->modifyTime; } + [[nodiscard]] auto modifyTime() const -> QString { return d_ptr->modifyTime; } void setSize(const QString &size) { d_ptr->size = size; } - QString size() const { return d_ptr->size; } + [[nodiscard]] auto size() const -> QString { return d_ptr->size; } void setChecked(bool checked) { d_ptr->checked = checked; } - bool checked() const { return d_ptr->checked; } + [[nodiscard]] auto checked() const -> bool { return d_ptr->checked; } private: QExplicitlySharedDataPointer d_ptr; diff --git a/TreeViewModel/fileitem.hpp b/TreeViewModel/fileitem.hpp index 57fa978..3ead5d3 100644 --- a/TreeViewModel/fileitem.hpp +++ b/TreeViewModel/fileitem.hpp @@ -9,14 +9,14 @@ class FileInfo; class FileItem : public TreeItem { public: - FileItem(const QFileInfo &fileInfo, bool depth = false); - ~FileItem(); + explicit FileItem(const QFileInfo &fileInfo, bool depth = false); + ~FileItem() override; - QVariant data(int column, int role) const override; - bool setData(int column, const QVariant &data, int role) override; - Qt::ItemFlags flags(int column) const override; + [[nodiscard]] auto data(int column, int role) const -> QVariant override; + auto setData(int column, const QVariant &data, int role) -> bool override; + [[nodiscard]] auto flags(int column) const -> Qt::ItemFlags override; - FileInfo fileInfo() const; + [[nodiscard]] auto fileInfo() const -> FileInfo; private: void init(); diff --git a/TreeViewModel/listview.hpp b/TreeViewModel/listview.hpp index 3726d8b..3d5b9ef 100644 --- a/TreeViewModel/listview.hpp +++ b/TreeViewModel/listview.hpp @@ -10,7 +10,7 @@ class ListView : public TreeView Q_OBJECT public: explicit ListView(QWidget *parent = nullptr); - ~ListView(); + ~ListView() override; void setDatas(const QFileInfoList &fileInfos); diff --git a/TreeViewModel/main.cc b/TreeViewModel/main.cc index e9bbf59..5d48a9d 100644 --- a/TreeViewModel/main.cc +++ b/TreeViewModel/main.cc @@ -7,7 +7,7 @@ #include #endif -int main(int argc, char *argv[]) +auto main(int argc, char *argv[]) -> int { QApplication a(argc, argv); MainWindow w; diff --git a/TreeViewModel/mainwindow.hpp b/TreeViewModel/mainwindow.hpp index 51b84cf..f0b50e9 100644 --- a/TreeViewModel/mainwindow.hpp +++ b/TreeViewModel/mainwindow.hpp @@ -13,11 +13,11 @@ class MainWindow : public QMainWindow Q_OBJECT public: - MainWindow(QWidget *parent = nullptr); - ~MainWindow(); + explicit MainWindow(QWidget *parent = nullptr); + ~MainWindow() override; protected: - void resizeEvent(QResizeEvent *event); + void resizeEvent(QResizeEvent *event) override; private: class MainWindowPrivate; diff --git a/TreeViewModel/normaltreeview.cc b/TreeViewModel/normaltreeview.cc index 305499c..d294bc1 100644 --- a/TreeViewModel/normaltreeview.cc +++ b/TreeViewModel/normaltreeview.cc @@ -26,12 +26,13 @@ void NormalTreeModel::setDatas(const QFileInfoList &fileInfos, bool depth) emit layoutChanged(); } -int NormalTreeModel::rowCount(const QModelIndex &idx) const +auto NormalTreeModel::rowCount(const QModelIndex &idx) const -> int { return BaseTreeModel::rowCount(idx); } -QVariant NormalTreeModel::headerData(int section, Qt::Orientation orientation, int role) const +auto NormalTreeModel::headerData(int section, Qt::Orientation orientation, int role) const + -> QVariant { switch (role) { case Qt::TextAlignmentRole: return Qt::AlignVCenter; @@ -51,13 +52,13 @@ QVariant NormalTreeModel::headerData(int section, Qt::Orientation orientation, i } break; default: break; } - return QVariant(); + return {}; } class NormalTreeView::NormalTreeViewPrivate { public: - NormalTreeViewPrivate(QWidget *parent) + explicit NormalTreeViewPrivate(QWidget *parent) : owner(parent) , model(new NormalTreeModel(owner)) {} @@ -74,7 +75,7 @@ NormalTreeView::NormalTreeView(QWidget *parent) setupUI(); } -NormalTreeView::~NormalTreeView() {} +NormalTreeView::~NormalTreeView() = default; void NormalTreeView::setDatas(const QFileInfoList &fileInfos) { diff --git a/TreeViewModel/normaltreeview.hpp b/TreeViewModel/normaltreeview.hpp index f3a66b7..58a65a6 100644 --- a/TreeViewModel/normaltreeview.hpp +++ b/TreeViewModel/normaltreeview.hpp @@ -16,11 +16,15 @@ class NormalTreeModel : public BaseTreeModel void setDatas(const QFileInfoList &fileInfos, bool depth = false); - int rowCount(const QModelIndex &idx = QModelIndex()) const override; + [[nodiscard]] auto rowCount(const QModelIndex &idx = QModelIndex()) const -> int override; protected: - int columnCount(const QModelIndex &idx) const override { return m_headerList.size(); } - QVariant headerData(int section, Qt::Orientation orientation, int role) const override; + [[nodiscard]] auto columnCount(const QModelIndex &idx) const -> int override + { + return m_headerList.size(); + } + [[nodiscard]] auto headerData(int section, Qt::Orientation orientation, int role) const + -> QVariant override; private: QStringList m_headerList; @@ -31,7 +35,7 @@ class NormalTreeView : public TreeView Q_OBJECT public: explicit NormalTreeView(QWidget *parent = nullptr); - ~NormalTreeView(); + ~NormalTreeView() override; void setDatas(const QFileInfoList &fileInfos); diff --git a/TreeViewModel/treemodel.cc b/TreeViewModel/treemodel.cc index 6aab15e..da0c10b 100644 --- a/TreeViewModel/treemodel.cc +++ b/TreeViewModel/treemodel.cc @@ -20,26 +20,26 @@ TreeItem::~TreeItem() removeChildren(); } -TreeItem *TreeItem::childAt(int pos) const +auto TreeItem::childAt(int pos) const -> TreeItem * { QTC_ASSERT(pos >= 0, return nullptr); return pos < childCount() ? *(begin() + pos) : nullptr; } -int TreeItem::indexOf(const TreeItem *item) const +auto TreeItem::indexOf(const TreeItem *item) const -> int { auto it = std::find(begin(), end(), item); return it == end() ? -1 : it - begin(); } -QVariant TreeItem::data(int column, int role) const +auto TreeItem::data(int column, int role) const -> QVariant { Q_UNUSED(column) Q_UNUSED(role) - return QVariant(); + return {}; } -bool TreeItem::setData(int column, const QVariant &data, int role) +auto TreeItem::setData(int column, const QVariant &data, int role) -> bool { Q_UNUSED(column) Q_UNUSED(data) @@ -47,18 +47,18 @@ bool TreeItem::setData(int column, const QVariant &data, int role) return false; } -Qt::ItemFlags TreeItem::flags(int column) const +auto TreeItem::flags(int column) const -> Qt::ItemFlags { Q_UNUSED(column) return Qt::ItemIsEnabled | Qt::ItemIsSelectable; } -bool TreeItem::hasChildren() const +auto TreeItem::hasChildren() const -> bool { return canFetchMore() || childCount() > 0; } -bool TreeItem::canFetchMore() const +auto TreeItem::canFetchMore() const -> bool { return false; } @@ -177,17 +177,17 @@ void TreeItem::updateColumn(int column) } } -TreeItem *TreeItem::firstChild() const +auto TreeItem::firstChild() const -> TreeItem * { return childCount() == 0 ? nullptr : *begin(); } -TreeItem *TreeItem::lastChild() const +auto TreeItem::lastChild() const -> TreeItem * { return childCount() == 0 ? nullptr : *(end() - 1); } -int TreeItem::level() const +auto TreeItem::level() const -> int { int l = 0; for (TreeItem *item = this->parent(); item; item = item->parent()) @@ -195,18 +195,18 @@ int TreeItem::level() const return l; } -int TreeItem::indexInParent() const +auto TreeItem::indexInParent() const -> int { return m_parent ? m_parent->indexOf(this) : -1; } -QModelIndex TreeItem::index() const +auto TreeItem::index() const -> QModelIndex { QTC_ASSERT(m_model, return QModelIndex()); return m_model->indexForItem(this); } -QAbstractItemModel *TreeItem::model() const +auto TreeItem::model() const -> QAbstractItemModel * { return m_model; } @@ -239,7 +239,7 @@ void TreeItem::forChildrenAtLevel(int level, const std::function &pred) const +auto TreeItem::findChildAtLevel(int level, const std::function &pred) const -> TreeItem * { QTC_ASSERT(level > 0, return nullptr); if (level == 1) { @@ -255,7 +255,7 @@ TreeItem *TreeItem::findChildAtLevel(int level, const std::function &pred) const +auto TreeItem::findAnyChild(const std::function &pred) const -> TreeItem * { for (TreeItem *item : *this) { if (pred(item)) @@ -266,7 +266,7 @@ TreeItem *TreeItem::findAnyChild(const std::function &pred) co return nullptr; } -TreeItem *TreeItem::reverseFindAnyChild(const std::function &pred) const +auto TreeItem::reverseFindAnyChild(const std::function &pred) const -> TreeItem * { auto end = m_children.rend(); for (auto it = m_children.rbegin(); it != end; ++it) { @@ -355,28 +355,28 @@ BaseTreeModel::~BaseTreeModel() delete m_root; } -QModelIndex BaseTreeModel::parent(const QModelIndex &idx) const +auto BaseTreeModel::parent(const QModelIndex &idx) const -> QModelIndex { CHECK_INDEX(idx); if (!idx.isValid()) - return QModelIndex(); + return {}; const TreeItem *item = itemForIndex(idx); QTC_ASSERT(item, return QModelIndex()); TreeItem *parent = item->parent(); if (!parent || parent == m_root) - return QModelIndex(); + return {}; const TreeItem *grandparent = parent->parent(); if (!grandparent) - return QModelIndex(); + return {}; // This is on the performance-critical path for ItemViewFind. const int i = grandparent->m_children.indexOf(parent); return createIndex(i, 0, static_cast(parent)); } -QModelIndex BaseTreeModel::sibling(int row, int column, const QModelIndex &idx) const +auto BaseTreeModel::sibling(int row, int column, const QModelIndex &idx) const -> QModelIndex { const TreeItem *item = itemForIndex(idx); QTC_ASSERT(item, return QModelIndex()); @@ -388,7 +388,7 @@ QModelIndex BaseTreeModel::sibling(int row, int column, const QModelIndex &idx) return result; } -int BaseTreeModel::rowCount(const QModelIndex &idx) const +auto BaseTreeModel::rowCount(const QModelIndex &idx) const -> int { CHECK_INDEX(idx); if (!idx.isValid()) @@ -399,7 +399,7 @@ int BaseTreeModel::rowCount(const QModelIndex &idx) const return item ? item->childCount() : 0; } -int BaseTreeModel::columnCount(const QModelIndex &idx) const +auto BaseTreeModel::columnCount(const QModelIndex &idx) const -> int { CHECK_INDEX(idx); if (idx.column() > 0) @@ -407,7 +407,7 @@ int BaseTreeModel::columnCount(const QModelIndex &idx) const return m_columnCount; } -bool BaseTreeModel::setData(const QModelIndex &idx, const QVariant &data, int role) +auto BaseTreeModel::setData(const QModelIndex &idx, const QVariant &data, int role) -> bool { TreeItem *item = itemForIndex(idx); bool res = item ? item->setData(idx.column(), data, role) : false; @@ -417,22 +417,22 @@ bool BaseTreeModel::setData(const QModelIndex &idx, const QVariant &data, int ro return res; } -QVariant BaseTreeModel::data(const QModelIndex &idx, int role) const +auto BaseTreeModel::data(const QModelIndex &idx, int role) const -> QVariant { TreeItem *item = itemForIndex(idx); return item ? item->data(idx.column(), role) : QVariant(); } -QVariant BaseTreeModel::headerData(int section, Qt::Orientation orientation, int role) const +auto BaseTreeModel::headerData(int section, Qt::Orientation orientation, int role) const -> QVariant { if (orientation == Qt::Horizontal && role == Qt::DisplayRole && section < m_header.size()) return m_header.at(section); if (role == Qt::ToolTipRole && section < m_headerToolTip.size()) return m_headerToolTip.at(section); - return QVariant(); + return {}; } -bool BaseTreeModel::hasChildren(const QModelIndex &idx) const +auto BaseTreeModel::hasChildren(const QModelIndex &idx) const -> bool { if (idx.column() > 0) return false; @@ -440,7 +440,7 @@ bool BaseTreeModel::hasChildren(const QModelIndex &idx) const return !item || item->hasChildren(); } -Qt::ItemFlags BaseTreeModel::flags(const QModelIndex &idx) const +auto BaseTreeModel::flags(const QModelIndex &idx) const -> Qt::ItemFlags { if (!idx.isValid()) return {}; @@ -448,7 +448,7 @@ Qt::ItemFlags BaseTreeModel::flags(const QModelIndex &idx) const return item ? item->flags(idx.column()) : (Qt::ItemIsEnabled | Qt::ItemIsSelectable); } -bool BaseTreeModel::canFetchMore(const QModelIndex &idx) const +auto BaseTreeModel::canFetchMore(const QModelIndex &idx) const -> bool { if (!idx.isValid()) return false; @@ -465,7 +465,7 @@ void BaseTreeModel::fetchMore(const QModelIndex &idx) item->fetchMore(); } -TreeItem *BaseTreeModel::rootItem() const +auto BaseTreeModel::rootItem() const -> TreeItem * { return m_root; } @@ -504,20 +504,20 @@ void BaseTreeModel::setHeaderToolTip(const QStringList &tips) m_headerToolTip = tips; } -QModelIndex BaseTreeModel::index(int row, int column, const QModelIndex &parent) const +auto BaseTreeModel::index(int row, int column, const QModelIndex &parent) const -> QModelIndex { CHECK_INDEX(parent); if (!hasIndex(row, column, parent)) - return QModelIndex(); + return {}; TreeItem *item = itemForIndex(parent); QTC_ASSERT(item, return QModelIndex()); if (row >= item->childCount()) - return QModelIndex(); + return {}; return createIndex(row, column, static_cast(item->childAt(row))); } -TreeItem *BaseTreeModel::itemForIndex(const QModelIndex &idx) const +auto BaseTreeModel::itemForIndex(const QModelIndex &idx) const -> TreeItem * { CHECK_INDEX(idx); TreeItem *item = idx.isValid() ? static_cast(idx.internalPointer()) : m_root; @@ -526,11 +526,11 @@ TreeItem *BaseTreeModel::itemForIndex(const QModelIndex &idx) const return item; } -QModelIndex BaseTreeModel::indexForItem(const TreeItem *item) const +auto BaseTreeModel::indexForItem(const TreeItem *item) const -> QModelIndex { QTC_ASSERT(item, return QModelIndex()); if (item == m_root) - return QModelIndex(); + return {}; TreeItem *p = item->parent(); QTC_ASSERT(p, return QModelIndex()); @@ -555,7 +555,7 @@ void BaseTreeModel::clear() \note The item is not destroyed, ownership is effectively passed to the caller. */ -TreeItem *BaseTreeModel::takeItem(TreeItem *item) +auto BaseTreeModel::takeItem(TreeItem *item) -> TreeItem * { #if USE_MODEL_TEST (void) new ModelTest(this, this); diff --git a/TreeViewModel/treemodel.hpp b/TreeViewModel/treemodel.hpp index 81946b0..4836f76 100644 --- a/TreeViewModel/treemodel.hpp +++ b/TreeViewModel/treemodel.hpp @@ -43,15 +43,15 @@ class TreeItem TreeItem(); virtual ~TreeItem(); - virtual QVariant data(int column, int role) const; - virtual bool setData(int column, const QVariant &data, int role); - virtual Qt::ItemFlags flags(int column) const; + [[nodiscard]] virtual auto data(int column, int role) const -> QVariant; + virtual auto setData(int column, const QVariant &data, int role) -> bool; + [[nodiscard]] virtual Qt::ItemFlags flags(int column) const; - virtual bool hasChildren() const; - virtual bool canFetchMore() const; + [[nodiscard]] virtual auto hasChildren() const -> bool; + [[nodiscard]] virtual auto canFetchMore() const -> bool; virtual void fetchMore() {} - TreeItem *parent() const { return m_parent; } + [[nodiscard]] auto parent() const -> TreeItem * { return m_parent; } void prependChild(TreeItem *item); void appendChild(TreeItem *item); @@ -67,31 +67,34 @@ class TreeItem void updateColumn(int column); void expand(); void collapse(); - TreeItem *firstChild() const; - TreeItem *lastChild() const; - int level() const; + [[nodiscard]] auto firstChild() const -> TreeItem *; + [[nodiscard]] auto lastChild() const -> TreeItem *; + [[nodiscard]] auto level() const -> int; using const_iterator = QVector::const_iterator; using value_type = TreeItem *; - int childCount() const { return m_children.size(); } - int indexInParent() const; - TreeItem *childAt(int index) const; - int indexOf(const TreeItem *item) const; - const_iterator begin() const { return m_children.begin(); } - const_iterator end() const { return m_children.end(); } - QModelIndex index() const; - QAbstractItemModel *model() const; + [[nodiscard]] auto childCount() const -> int { return m_children.size(); } + [[nodiscard]] auto indexInParent() const -> int; + [[nodiscard]] auto childAt(int index) const -> TreeItem *; + auto indexOf(const TreeItem *item) const -> int; + [[nodiscard]] const_iterator begin() const { return m_children.begin(); } + [[nodiscard]] const_iterator end() const { return m_children.end(); } + [[nodiscard]] auto index() const -> QModelIndex; + [[nodiscard]] auto model() const -> QAbstractItemModel *; void forSelectedChildren(const std::function &pred) const; void forAllChildren(const std::function &pred) const; - TreeItem *findAnyChild(const std::function &pred) const; + [[nodiscard]] auto findAnyChild(const std::function &pred) const + -> TreeItem *; // like findAnyChild() but processes children in exact reverse order // (bottom to top, most inner children first) - TreeItem *reverseFindAnyChild(const std::function &pred) const; + [[nodiscard]] auto reverseFindAnyChild(const std::function &pred) const + -> TreeItem *; // Levels are 1-based: Child at Level 1 is an immediate child. void forChildrenAtLevel(int level, const std::function &pred) const; - TreeItem *findChildAtLevel(int level, const std::function &pred) const; + [[nodiscard]] auto findChildAtLevel(int level, const std::function &pred) const + -> TreeItem *; private: TreeItem(const TreeItem &) = delete; @@ -122,28 +125,31 @@ class BaseTreeModel : public QAbstractItemModel void setHeaderToolTip(const QStringList &tips); void clear(); - TreeItem *rootItem() const; + [[nodiscard]] auto rootItem() const -> TreeItem *; void setRootItem(TreeItem *item); - TreeItem *itemForIndex(const QModelIndex &) const; - QModelIndex indexForItem(const TreeItem *needle) const; - - int rowCount(const QModelIndex &idx = QModelIndex()) const override; - int columnCount(const QModelIndex &idx) const override; - - bool setData(const QModelIndex &idx, const QVariant &data, int role) override; - QVariant data(const QModelIndex &idx, int role) const override; - QModelIndex index(int, int, const QModelIndex &idx = QModelIndex()) const override; - QModelIndex parent(const QModelIndex &idx) const override; - QModelIndex sibling(int row, int column, const QModelIndex &idx) const override; - Qt::ItemFlags flags(const QModelIndex &idx) const override; - QVariant headerData(int section, Qt::Orientation orientation, int role) const override; - bool hasChildren(const QModelIndex &idx) const override; - - bool canFetchMore(const QModelIndex &idx) const override; + [[nodiscard]] auto itemForIndex(const QModelIndex &) const -> TreeItem *; + auto indexForItem(const TreeItem *needle) const -> QModelIndex; + + [[nodiscard]] auto rowCount(const QModelIndex &idx = QModelIndex()) const -> int override; + [[nodiscard]] auto columnCount(const QModelIndex &idx) const -> int override; + + auto setData(const QModelIndex &idx, const QVariant &data, int role) -> bool override; + [[nodiscard]] auto data(const QModelIndex &idx, int role) const -> QVariant override; + [[nodiscard]] auto index(int, int, const QModelIndex &idx = QModelIndex()) const + -> QModelIndex override; + [[nodiscard]] auto parent(const QModelIndex &idx) const -> QModelIndex override; + [[nodiscard]] auto sibling(int row, int column, const QModelIndex &idx) const + -> QModelIndex override; + [[nodiscard]] Qt::ItemFlags flags(const QModelIndex &idx) const override; + [[nodiscard]] auto headerData(int section, Qt::Orientation orientation, int role) const + -> QVariant override; + [[nodiscard]] auto hasChildren(const QModelIndex &idx) const -> bool override; + + [[nodiscard]] auto canFetchMore(const QModelIndex &idx) const -> bool override; void fetchMore(const QModelIndex &idx) override; - TreeItem *takeItem(TreeItem *item); // item is not destroyed. - void destroyItem(TreeItem *item); // item is destroyed. + auto takeItem(TreeItem *item) -> TreeItem *; // item is not destroyed. + void destroyItem(TreeItem *item); // item is destroyed. signals: void requestExpansion(const QModelIndex &); diff --git a/TreeViewModel/treeview.cc b/TreeViewModel/treeview.cc index 5f7a2a9..8d09f2f 100644 --- a/TreeViewModel/treeview.cc +++ b/TreeViewModel/treeview.cc @@ -12,7 +12,7 @@ TreeView::TreeView(QWidget *parent) buildConnect(); } -QModelIndexList TreeView::selectedIndexes() const +auto TreeView::selectedIndexes() const -> QModelIndexList { QModelIndexList indexList(QTreeView::selectedIndexes()); QModelIndexList list; @@ -26,7 +26,7 @@ QModelIndexList TreeView::selectedIndexes() const return list; } -QModelIndexList TreeView::allIndexes() const +auto TreeView::allIndexes() const -> QModelIndexList { QModelIndexList list; QAbstractItemModel *model = this->model(); @@ -39,7 +39,7 @@ QModelIndexList TreeView::allIndexes() const return list; } -int TreeView::pageSize() +auto TreeView::pageSize() -> int { m_pageSize = height() / 50 + 2; return m_pageSize; diff --git a/TreeViewModel/treeview.hpp b/TreeViewModel/treeview.hpp index 7c0d8cc..f1075b1 100644 --- a/TreeViewModel/treeview.hpp +++ b/TreeViewModel/treeview.hpp @@ -9,11 +9,11 @@ class TreeView : public QTreeView public: explicit TreeView(QWidget *parent = nullptr); - QModelIndexList selectedIndexes() const; + [[nodiscard]] auto selectedIndexes() const -> QModelIndexList override; - QModelIndexList allIndexes() const; + [[nodiscard]] auto allIndexes() const -> QModelIndexList; - virtual int pageSize(); + virtual auto pageSize() -> int; signals: void selectedChanged(); @@ -27,7 +27,7 @@ private slots: void onFetchMore(int value); protected: - void showEvent(QShowEvent *event); + void showEvent(QShowEvent *event) override; protected: int m_pageSize = 20; diff --git a/Validator/main.cc b/Validator/main.cc index e9bbf59..5d48a9d 100644 --- a/Validator/main.cc +++ b/Validator/main.cc @@ -7,7 +7,7 @@ #include #endif -int main(int argc, char *argv[]) +auto main(int argc, char *argv[]) -> int { QApplication a(argc, argv); MainWindow w; diff --git a/Validator/mainwindow.hpp b/Validator/mainwindow.hpp index 2a84cf2..971b4a4 100644 --- a/Validator/mainwindow.hpp +++ b/Validator/mainwindow.hpp @@ -1,19 +1,14 @@ #ifndef MAINWINDOW_HPP #define MAINWINDOW_HPP -#include -#if QT_VERSION >= 0x050000 -#include -#else -#include -#endif +#include class MainWindow : public QMainWindow { Q_OBJECT - - public: - MainWindow(QWidget *parent = nullptr); - ~MainWindow(); +public: + explicit MainWindow(QWidget *parent = nullptr); + ~MainWindow() override; }; + #endif // MAINWINDOW_HPP diff --git a/Validator/validator.cc b/Validator/validator.cc index 126c01e..7999438 100644 --- a/Validator/validator.cc +++ b/Validator/validator.cc @@ -1,6 +1,6 @@ #include "validator.hpp" -QValidator::State IntValidator::validate(QString &input, int &pos) const +auto IntValidator::validate(QString &input, int &pos) const -> QValidator::State { const State originalRes = QIntValidator::validate(input, pos); if (originalRes != Intermediate || input.isEmpty()) { @@ -18,7 +18,7 @@ QValidator::State IntValidator::validate(QString &input, int &pos) const return originalRes; } -QValidator::State DoubleValidator::validate(QString &input, int &pos) const +auto DoubleValidator::validate(QString &input, int &pos) const -> QValidator::State { const State originalRes = QDoubleValidator::validate(input, pos); if (originalRes != Intermediate || input.isEmpty()) { diff --git a/Validator/validator.hpp b/Validator/validator.hpp index 6e08114..d8dedd9 100644 --- a/Validator/validator.hpp +++ b/Validator/validator.hpp @@ -9,7 +9,7 @@ class IntValidator : public QIntValidator public: using QIntValidator::QIntValidator; - State validate(QString &input, int &pos) const override; + auto validate(QString &input, int &pos) const -> State override; }; class DoubleValidator : public QDoubleValidator @@ -18,7 +18,7 @@ class DoubleValidator : public QDoubleValidator public: using QDoubleValidator::QDoubleValidator; - State validate(QString &input, int &pos) const override; + auto validate(QString &input, int &pos) const -> State override; }; #endif // VALIDATOR_HPP