commit 3796ec5cd2bbc1b437a2278985a3a0d913b925e1 Author: 小林泉酱 Date: Fri Nov 6 01:04:35 2026 +0800 First Commit diff --git a/Projects/.gitignore b/Projects/.gitignore new file mode 100644 index 0000000..6447480 --- /dev/null +++ b/Projects/.gitignore @@ -0,0 +1,6 @@ +build*/ +*.user +*.user.* +*.autosave +.DS_Store + diff --git a/Projects/01_UnitConverter/CMakeLists.txt b/Projects/01_UnitConverter/CMakeLists.txt new file mode 100644 index 0000000..f2de709 --- /dev/null +++ b/Projects/01_UnitConverter/CMakeLists.txt @@ -0,0 +1,33 @@ +cmake_minimum_required(VERSION 3.16) +project(UnitConverter VERSION 1.0 LANGUAGES CXX) +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTOUIC ON) +set(CMAKE_CXX_STANDARD 14) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) +find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets) +find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets) +if(QT_VERSION_MAJOR EQUAL 5 AND Qt5Core_VERSION VERSION_LESS 5.14.2) + message(FATAL_ERROR "Qt 5.14.2 or newer is required.") +endif() +if(QT_VERSION_MAJOR EQUAL 6) + set(CMAKE_CXX_STANDARD 17) +endif() +if(MSVC) + add_compile_options(/utf-8) +else() + add_compile_options(-Wall -Wextra -Wpedantic) +endif() +add_executable(UnitConverter WIN32 main.cpp appearance.h mainwindow.cpp mainwindow.h conversion.cpp conversion.h mainwindow.ui) +target_link_libraries(UnitConverter PRIVATE Qt${QT_VERSION_MAJOR}::Widgets) +option(BUILD_TEACHING_TESTS "Build teaching project tests" OFF) +if(BUILD_TEACHING_TESTS) + enable_testing() + find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Test) + add_executable(test_UnitConverter tests/test_UnitConverter.cpp mainwindow.cpp mainwindow.h + conversion.cpp conversion.h mainwindow.ui) + target_include_directories(test_UnitConverter PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) + target_link_libraries(test_UnitConverter PRIVATE Qt${QT_VERSION_MAJOR}::Widgets Qt${QT_VERSION_MAJOR}::Test) + add_test(NAME UnitConverter COMMAND test_UnitConverter -platform offscreen) +endif() + diff --git a/Projects/01_UnitConverter/README.md b/Projects/01_UnitConverter/README.md new file mode 100644 index 0000000..0d0ed94 --- /dev/null +++ b/Projects/01_UnitConverter/README.md @@ -0,0 +1,59 @@ +# 项目一:单位换算器 + +适合第2—3章讲解信号槽、组件访问和函数分工,第4章可继续练习下拉框与字符串处理。 + +## 运行后试什么 + +初始输入为 25,源单位为摄氏度,目标单位为华氏度。点击“换算”,应显示 77 °F,并在下方显示公式。也可以在输入框内按 Enter。 + +切换到长度后,默认将米换成厘米。输入 1,结果应为 100 cm。“交换单位”只交换源单位与目标单位,输入值保持不变。修改输入或单位会清空旧结果,防止把上次的答案当成当前答案。 + +支持摄氏度、华氏度、开尔文,以及毫米、厘米、米、千米、英寸和英尺。结果最多显示 12 位有效数字。 + +## 课堂任务 + +第一步只保留温度输入、换算按钮和结果框。让学生完成摄氏度到华氏度的换算,并解释输入框返回的是字符串,计算需要数值。 + +第二步加入返回值检查。分别输入空字符串、abc 和 25.5,观察程序怎样决定是否继续计算。当前工程用完整字符串的格式检查配合 toDouble,支持小数和科学计数法,不接受千位分隔符。 + +第三步加入源单位和目标单位。先统一到摄氏度,再计算目标温度。让学生画出华氏度到开尔文的两步过程,避免只背诵一个总公式。 + +第四步加入长度换算。单位比例写在数组中,先解释数组下标与下拉框顺序的对应关系,再讨论增加一个单位时需要修改哪些位置。 + +## 一次换算怎样完成 + +1. convertButton 发出 clicked 信号,调用 convertValue。 +2. 主窗口读取 inputEdit 的文本和两个下拉框的索引。 +3. Conversion::convert 检查输入,计算结果,返回 Result。 +4. 主窗口根据 Result::ok 显示结果或错误原因。 +5. 计算成功后允许复制;输入变化后立即禁用复制并清除旧结果。 + +Conversion::convert 不直接操作输入框或标签,因此可以使用不同界面调用,也可以单独测试。 + +## 需要解释的条件 + +- 温度不能低于绝对零度。摄氏度下限为 −273.15,华氏度下限为 −459.67,开尔文下限为 0。 +- 边界比较保留极小的浮点误差余量,防止换算时的舍入把绝对零度判为非法值。 +- 本工具中的长度表示非负长度,不表示带方向的坐标位移。 +- 输入可以合法,但结果仍可能溢出。输入检查和结果检查分别负责两个阶段。 +- 显示的有效数字有限,程序不承诺任意精度计算。 + +## 学生练习 + +1. 增加“码”,已知 1 yd = 0.9144 m。检查它与米、英尺之间的换算。 +2. 增加“使用本次结果继续换算”按钮,说明它与“交换单位”的区别。 +3. 为结果增加可选择的显示精度,并解释显示精度为什么不等于计算精度。 + +## 验收用例 + +| 操作 | 预期 | +|---|---| +| 0 °C → °F | 32 | +| 212 °F → °C | 100 | +| −459.67 °F → K | 0 | +| −274 °C → K | 显示低于绝对零度的提示 | +| 1 in → cm | 2.54 | +| 1 ft → m | 0.3048 | +| 输入 12abc、nan 或 1,000 | 拒绝计算 | +| 算出结果后修改输入 | 旧结果清空,复制按钮不可用 | + diff --git a/Projects/01_UnitConverter/UnitConverter.pro b/Projects/01_UnitConverter/UnitConverter.pro new file mode 100644 index 0000000..7174d47 --- /dev/null +++ b/Projects/01_UnitConverter/UnitConverter.pro @@ -0,0 +1,10 @@ +QT += widgets +CONFIG += c++14 +greaterThan(QT_MAJOR_VERSION, 5): CONFIG += c++17 +TEMPLATE = app +TARGET = UnitConverter +SOURCES += main.cpp mainwindow.cpp conversion.cpp +HEADERS += mainwindow.h conversion.h +FORMS += mainwindow.ui +msvc: QMAKE_CXXFLAGS += /utf-8 + diff --git a/Projects/01_UnitConverter/appearance.h b/Projects/01_UnitConverter/appearance.h new file mode 100644 index 0000000..16d3436 --- /dev/null +++ b/Projects/01_UnitConverter/appearance.h @@ -0,0 +1,34 @@ +#pragma once +#include +#include +#include + +inline void applyAppearance(QApplication &app) +{ + app.setStyle(QStyleFactory::create(QStringLiteral("Fusion"))); + app.setFont(QFont(QStringLiteral("Microsoft YaHei UI"), 11)); + app.setStyleSheet(QStringLiteral( + "QMainWindow { background: #f5f7fb; }" + "QLabel { color: #23364c; }" + "QLabel#titleLabel { font-size: 27px; font-weight: bold; color: #173b63; }" + "QLabel#subtitleLabel, QLabel#helpLabel { color: #52657a; }" + "QGroupBox { background: white; border: 1px solid #d6e0eb;" + " border-radius: 8px; margin-top: 12px; padding: 18px 12px 12px; }" + "QGroupBox::title { subcontrol-origin: margin; left: 12px; padding: 0 6px; }" + "QLineEdit, QSpinBox, QComboBox { min-height: 32px; padding: 3px 8px; }" + "QLineEdit, QSpinBox, QComboBox, QPlainTextEdit, QListWidget" + " { background: white; color: #23364c; }" + "QPushButton { min-height: 34px; padding: 4px 14px; }" + "QPushButton#convertButton, QPushButton#startButton, QPushButton#drawButton," + " QPushButton#applyButton, QPushButton#groupsButton { background: #255c93;" + " color: white; border: 1px solid #255c93; border-radius: 5px; }" + "QPushButton:disabled, QPushButton#convertButton:disabled," + " QPushButton#startButton:disabled, QPushButton#drawButton:disabled," + " QPushButton#applyButton:disabled, QPushButton#groupsButton:disabled" + " { color: #8995a3; background: #e6ebf1; border-color: #d6e0eb; }" + "QLabel#statusLabel { color: #185376; }" + "QLineEdit#resultEdit { font-size: 23px; min-height: 45px; color: #175e53; }" + "QLabel#timeLabel { font: bold 76px 'Consolas'; color: #173b63; }" + "QProgressBar { border: 1px solid #d6e0eb; border-radius: 6px; height: 14px; }" + "QProgressBar::chunk { background: #2b8a7d; border-radius: 5px; }")); +} diff --git a/Projects/01_UnitConverter/conversion.cpp b/Projects/01_UnitConverter/conversion.cpp new file mode 100644 index 0000000..764ec06 --- /dev/null +++ b/Projects/01_UnitConverter/conversion.cpp @@ -0,0 +1,94 @@ +#include "conversion.h" +#include +#include + +namespace Conversion { +QStringList units(Category category) +{ + if (category == Category::Temperature) + return {QStringLiteral("摄氏度 °C"), QStringLiteral("华氏度 °F"), + QStringLiteral("开尔文 K")}; + return {QStringLiteral("毫米 mm"), QStringLiteral("厘米 cm"), + QStringLiteral("米 m"), QStringLiteral("千米 km"), + QStringLiteral("英寸 in"), QStringLiteral("英尺 ft")}; +} + +Result convert(const QString &text, Category category, int from, int to) +{ + Result result; + const QString input = text.trimmed(); + // 先检查完整输入,避免把“12abc”误当成有效数值。 + static const QRegularExpression number( + QStringLiteral("^[+-]?(?:[0-9]+(?:\\.[0-9]*)?|\\.[0-9]+)(?:[eE][+-]?[0-9]+)?$")); + if (!number.match(input).hasMatch()) { + result.error = QStringLiteral("请输入完整的数值,例如 25、-10.5 或 1e3;小数点使用英文句点。"); + return result; + } + bool ok = false; + const double value = input.toDouble(&ok); + if (!ok || !std::isfinite(value)) { + result.error = QStringLiteral("输入超出了可计算的数值范围,请减小数值。"); + return result; + } + const QStringList names = units(category); + if (from < 0 || to < 0 || from >= names.size() || to >= names.size()) { + result.error = QStringLiteral("请选择有效的单位。"); + return result; + } + if (category == Category::Temperature) { + // 先统一为摄氏度,再换算为目标单位,避免为每对单位各写一套公式。 + double celsius = value; + QString first; + if (from == 1) { + celsius = (value - 32.0) / 1.8; + first = QStringLiteral("先换成摄氏度:C = (F − 32) ÷ 1.8。"); + } else if (from == 2) { + celsius = value - 273.15; + first = QStringLiteral("先换成摄氏度:C = K − 273.15。"); + } else { + first = QStringLiteral("输入已经是摄氏度,可直接作为中间值。"); + } + if (celsius < -273.15 - 1e-9) { + result.error = QStringLiteral("温度不能低于绝对零度:−273.15 °C / −459.67 °F / 0 K。"); + return result; + } + // 允许边界处的浮点舍入误差,避免把绝对零度误判为非法输入。 + if (celsius < -273.15) + celsius = -273.15; + QString second; + if (to == 1) { + result.value = celsius * 1.8 + 32.0; + second = QStringLiteral("再换成华氏度:F = C × 1.8 + 32。"); + } else if (to == 2) { + result.value = celsius + 273.15; + second = QStringLiteral("再换成开尔文:K = C + 273.15。"); + } else { + result.value = celsius; + second = QStringLiteral("目标是摄氏度,中间值就是结果。"); + } + result.explanation = first + QStringLiteral("\n") + second; + } else { + if (value < 0.0) { + result.error = QStringLiteral("本工具换算的是长度,输入值不能为负数。"); + return result; + } + const double metersPerUnit[] = {0.001, 0.01, 1.0, 1000.0, 0.0254, 0.3048}; + result.value = value * (metersPerUnit[from] / metersPerUnit[to]); + result.explanation = + QStringLiteral("以米为统一单位:结果 = 输入值 × 源单位的米数 ÷ 目标单位的米数。\n" + "本次计算:%1 × %2 ÷ %3。") + .arg(input) + .arg(metersPerUnit[from], 0, 'g', 12) + .arg(metersPerUnit[to], 0, 'g', 12); + } + if (!std::isfinite(result.value)) { + result.error = QStringLiteral("换算结果超出了可显示的数值范围。"); + return result; + } + if (result.value == 0.0) + result.value = 0.0; // 避免显示 -0。 + result.ok = true; + return result; +} +} + diff --git a/Projects/01_UnitConverter/conversion.h b/Projects/01_UnitConverter/conversion.h new file mode 100644 index 0000000..5e59b92 --- /dev/null +++ b/Projects/01_UnitConverter/conversion.h @@ -0,0 +1,18 @@ +#pragma once +#include +#include + +namespace Conversion { +enum class Category { Temperature, Length }; + +struct Result { + bool ok = false; + double value = 0.0; + QString explanation; + QString error; +}; + +QStringList units(Category category); +Result convert(const QString &text, Category category, int from, int to); +} + diff --git a/Projects/01_UnitConverter/main.cpp b/Projects/01_UnitConverter/main.cpp new file mode 100644 index 0000000..d8f1ee0 --- /dev/null +++ b/Projects/01_UnitConverter/main.cpp @@ -0,0 +1,19 @@ +#include "mainwindow.h" +#include "appearance.h" +#include +#include +#include + +int main(int argc, char *argv[]) +{ +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) + QApplication::setAttribute(Qt::AA_EnableHighDpiScaling); + QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); +#endif + QApplication app(argc, argv); + applyAppearance(app); + MainWindow window; + window.show(); + return app.exec(); +} + diff --git a/Projects/01_UnitConverter/mainwindow.cpp b/Projects/01_UnitConverter/mainwindow.cpp new file mode 100644 index 0000000..866d6ae --- /dev/null +++ b/Projects/01_UnitConverter/mainwindow.cpp @@ -0,0 +1,83 @@ +#include "mainwindow.h" +#include "ui_mainwindow.h" +#include "conversion.h" +#include +#include + +MainWindow::MainWindow(QWidget *parent) + : QMainWindow(parent), ui(new Ui::MainWindow) +{ + ui->setupUi(this); + ui->categoryCombo->addItems({tr("温度"), tr("长度")}); + connect(ui->categoryCombo, static_cast(&QComboBox::currentIndexChanged), + this, &MainWindow::changeCategory); + connect(ui->convertButton, &QPushButton::clicked, this, &MainWindow::convertValue); + connect(ui->inputEdit, &QLineEdit::returnPressed, this, &MainWindow::convertValue); + connect(ui->inputEdit, &QLineEdit::textChanged, this, &MainWindow::clearResult); + connect(ui->fromCombo, static_cast(&QComboBox::currentIndexChanged), + this, &MainWindow::clearResult); + connect(ui->toCombo, static_cast(&QComboBox::currentIndexChanged), + this, &MainWindow::clearResult); + connect(ui->swapButton, &QPushButton::clicked, this, [this] { + const int previousFrom = ui->fromCombo->currentIndex(); + ui->fromCombo->setCurrentIndex(ui->toCombo->currentIndex()); + ui->toCombo->setCurrentIndex(previousFrom); + ui->inputEdit->setFocus(); + }); + connect(ui->clearButton, &QPushButton::clicked, this, [this] { + ui->inputEdit->clear(); + clearResult(); + ui->inputEdit->setFocus(); + }); + connect(ui->copyButton, &QPushButton::clicked, this, [this] { + QApplication::clipboard()->setText(ui->resultEdit->text()); + ui->statusLabel->setText(tr("结果已复制。")); + }); + changeCategory(); + ui->inputEdit->setText(QStringLiteral("25")); +} + +MainWindow::~MainWindow() { delete ui; } + +void MainWindow::changeCategory() +{ + const auto category = ui->categoryCombo->currentIndex() == 0 + ? Conversion::Category::Temperature : Conversion::Category::Length; + const QStringList names = Conversion::units(category); + ui->fromCombo->clear(); + ui->toCombo->clear(); + ui->fromCombo->addItems(names); + ui->toCombo->addItems(names); + ui->fromCombo->setCurrentIndex(category == Conversion::Category::Length ? 2 : 0); + ui->toCombo->setCurrentIndex(1); + clearResult(); +} + +void MainWindow::clearResult() +{ + ui->resultEdit->clear(); + ui->formulaLabel->setText(tr("选择单位并输入数值,点击“换算”查看计算过程。")); + ui->statusLabel->clear(); + ui->copyButton->setEnabled(false); +} + +void MainWindow::convertValue() +{ + const auto category = ui->categoryCombo->currentIndex() == 0 + ? Conversion::Category::Temperature : Conversion::Category::Length; + const auto result = Conversion::convert(ui->inputEdit->text(), category, + ui->fromCombo->currentIndex(), + ui->toCombo->currentIndex()); + if (!result.ok) { + clearResult(); + ui->statusLabel->setText(result.error); + ui->inputEdit->setFocus(); + return; + } + ui->resultEdit->setText(QStringLiteral("%1 %2") + .arg(result.value, 0, 'g', 12).arg(ui->toCombo->currentText())); + ui->formulaLabel->setText(result.explanation); + ui->statusLabel->setText(tr("换算完成。结果最多显示 12 位有效数字。")); + ui->copyButton->setEnabled(true); +} + diff --git a/Projects/01_UnitConverter/mainwindow.h b/Projects/01_UnitConverter/mainwindow.h new file mode 100644 index 0000000..1e60bff --- /dev/null +++ b/Projects/01_UnitConverter/mainwindow.h @@ -0,0 +1,16 @@ +#pragma once +#include +namespace Ui { class MainWindow; } + +class MainWindow : public QMainWindow { + Q_OBJECT +public: + explicit MainWindow(QWidget *parent = nullptr); + ~MainWindow() override; +private: + Ui::MainWindow *ui; + void changeCategory(); + void clearResult(); + void convertValue(); +}; + diff --git a/Projects/01_UnitConverter/mainwindow.ui b/Projects/01_UnitConverter/mainwindow.ui new file mode 100644 index 0000000..f78940c --- /dev/null +++ b/Projects/01_UnitConverter/mainwindow.ui @@ -0,0 +1,246 @@ + + + MainWindow + + + 单位换算器 + + + + 0 + 0 + 840 + 650 + + + + + + 12 + + + 24 + + + 24 + + + 24 + + + 24 + + + + + 单位换算器 + + + Qt::PlainText + + + + + + + 输入一个数值,查看换算结果和计算过程。 + + + Qt::PlainText + + + true + + + + + + + 输入与单位 + + + + 12 + + + + + 换算类型 + + + Qt::PlainText + + + + + + + 输入数值 + + + Qt::PlainText + + + + + + + + + + 例如 25、-10.5 或 1e3 + + + 100 + + + + + + + 源单位 + + + Qt::PlainText + + + + + + + 目标单位 + + + Qt::PlainText + + + + + + + + + + + + + + + + 12 + + + + + 换算 + + + true + + + + + + + 交换单位 + + + + + + + 清空输入 + + + + + + + + + 换算结果 + + + + 12 + + + + + true + + + 结果将在这里显示 + + + + + + + + + + Qt::PlainText + + + true + + + + 0 + 70 + + + + + + + + 复制结果 + + + false + + + + + + + + + + + + + Qt::PlainText + + + true + + + + 0 + 55 + + + + + + + + 长度须为非负数,温度须不低于绝对零度。修改输入或单位后,需要重新换算。 + + + Qt::PlainText + + + true + + + + + + + + + diff --git a/Projects/01_UnitConverter/tests/test_UnitConverter.cpp b/Projects/01_UnitConverter/tests/test_UnitConverter.cpp new file mode 100644 index 0000000..88a160e --- /dev/null +++ b/Projects/01_UnitConverter/tests/test_UnitConverter.cpp @@ -0,0 +1,90 @@ +#include +#include +#include +#include +#include +#include "conversion.h" +#include "mainwindow.h" +#include +#include +#include "appearance.h" + +static void savePreview(QWidget &window, const QString &fileName) +{ + const QString folder = QString::fromLocal8Bit(qgetenv("QT_TEACHING_SCREENSHOTS")); + if (folder.isEmpty()) return; + QDir().mkpath(folder); + window.show(); + QApplication::processEvents(); + QVERIFY(window.grab().save(QDir(folder).filePath(fileName))); +} + +class ConverterTest : public QObject { + Q_OBJECT +private slots: + void initTestCase() { applyAppearance(*qApp); } + void knownValues_data() + { + QTest::addColumn("category"); + QTest::addColumn("input"); + QTest::addColumn("from"); + QTest::addColumn("to"); + QTest::addColumn("expected"); + QTest::newRow("freezing") << 0 << QStringLiteral("0") << 0 << 1 << 32.0; + QTest::newRow("boiling") << 0 << QStringLiteral("212") << 1 << 0 << 100.0; + QTest::newRow("minus40") << 0 << QStringLiteral("-40") << 0 << 1 << -40.0; + QTest::newRow("kelvin") << 0 << QStringLiteral("273.15") << 2 << 0 << 0.0; + QTest::newRow("absolute-zero-C") << 0 << QStringLiteral("-273.15") << 0 << 2 << 0.0; + QTest::newRow("absolute-zero-F") << 0 << QStringLiteral("-459.67") << 1 << 2 << 0.0; + QTest::newRow("meter-cm") << 1 << QStringLiteral("1") << 2 << 1 << 100.0; + QTest::newRow("inch-cm") << 1 << QStringLiteral("1") << 4 << 1 << 2.54; + QTest::newRow("foot-meter") << 1 << QStringLiteral("1") << 5 << 2 << 0.3048; + QTest::newRow("km-mm") << 1 << QStringLiteral("1") << 3 << 0 << 1000000.0; + QTest::newRow("scientific") << 1 << QStringLiteral(" 1e3 ") << 0 << 2 << 1.0; + QTest::newRow("same-unit") << 1 << QStringLiteral("12.25") << 2 << 2 << 12.25; + } + void knownValues() + { + QFETCH(int, category); QFETCH(QString, input); + QFETCH(int, from); QFETCH(int, to); QFETCH(double, expected); + auto result = Conversion::convert(input, static_cast(category), from, to); + QVERIFY2(result.ok, qPrintable(result.error)); + QVERIFY(qAbs(result.value - expected) <= 1e-9 * qMax(1.0, qAbs(expected))); + } + void rejectsInvalid() + { + for (const QString &text : {QString(), QStringLiteral("12abc"), QStringLiteral("nan"), + QStringLiteral("inf"), QStringLiteral("1,000"), QStringLiteral("1e309")}) + QVERIFY(!Conversion::convert(text, Conversion::Category::Length, 2, 1).ok); + QVERIFY(!Conversion::convert(QStringLiteral("-1"), Conversion::Category::Length, 2, 1).ok); + QVERIFY(!Conversion::convert(QStringLiteral("-274"), Conversion::Category::Temperature, 0, 2).ok); + QVERIFY(!Conversion::convert(QStringLiteral("-0.1"), Conversion::Category::Temperature, 2, 0).ok); + QVERIFY(!Conversion::convert(QStringLiteral("1e308"), Conversion::Category::Length, 3, 0).ok); + } + void uiWorkflow() + { + MainWindow w; w.show(); + auto *input = w.findChild(QStringLiteral("inputEdit")); + auto *result = w.findChild(QStringLiteral("resultEdit")); + auto *convert = w.findChild(QStringLiteral("convertButton")); + input->setText(QStringLiteral("25")); + QTest::mouseClick(convert, Qt::LeftButton); + QVERIFY(result->text().startsWith(QStringLiteral("77 "))); + savePreview(w, QStringLiteral("01_converter.png")); + input->setText(QStringLiteral("bad")); + QVERIFY(result->text().isEmpty()); + QTest::mouseClick(convert, Qt::LeftButton); + QVERIFY(!w.findChild(QStringLiteral("statusLabel"))->text().isEmpty()); + QVERIFY(!w.findChild(QStringLiteral("copyButton"))->isEnabled()); + w.findChild(QStringLiteral("categoryCombo"))->setCurrentIndex(1); + input->setText(QStringLiteral("1")); + QTest::mouseClick(convert, Qt::LeftButton); + QVERIFY(result->text().startsWith(QStringLiteral("100 "))); + QTest::mouseClick(w.findChild(QStringLiteral("swapButton")), Qt::LeftButton); + QTest::mouseClick(convert, Qt::LeftButton); + QVERIFY(result->text().startsWith(QStringLiteral("0.01 "))); + } +}; +QTEST_MAIN(ConverterTest) +#include "test_UnitConverter.moc" + diff --git a/Projects/01_UnitConverter/tests/test_UnitConverter.pro b/Projects/01_UnitConverter/tests/test_UnitConverter.pro new file mode 100644 index 0000000..a2ade73 --- /dev/null +++ b/Projects/01_UnitConverter/tests/test_UnitConverter.pro @@ -0,0 +1,11 @@ +QT += widgets testlib +CONFIG += c++14 console testcase +greaterThan(QT_MAJOR_VERSION, 5): CONFIG += c++17 +TEMPLATE = app +TARGET = test_UnitConverter +INCLUDEPATH += .. +SOURCES += test_UnitConverter.cpp ../mainwindow.cpp ../conversion.cpp +HEADERS += ../mainwindow.h ../conversion.h +FORMS += ../mainwindow.ui +msvc: QMAKE_CXXFLAGS += /utf-8 + diff --git a/Projects/02_ClassroomTimer/CMakeLists.txt b/Projects/02_ClassroomTimer/CMakeLists.txt new file mode 100644 index 0000000..0105831 --- /dev/null +++ b/Projects/02_ClassroomTimer/CMakeLists.txt @@ -0,0 +1,33 @@ +cmake_minimum_required(VERSION 3.16) +project(ClassroomTimer VERSION 1.0 LANGUAGES CXX) +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTOUIC ON) +set(CMAKE_CXX_STANDARD 14) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) +find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets) +find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets) +if(QT_VERSION_MAJOR EQUAL 5 AND Qt5Core_VERSION VERSION_LESS 5.14.2) + message(FATAL_ERROR "Qt 5.14.2 or newer is required.") +endif() +if(QT_VERSION_MAJOR EQUAL 6) + set(CMAKE_CXX_STANDARD 17) +endif() +if(MSVC) + add_compile_options(/utf-8) +else() + add_compile_options(-Wall -Wextra -Wpedantic) +endif() +add_executable(ClassroomTimer WIN32 main.cpp appearance.h mainwindow.cpp mainwindow.h countdown.cpp countdown.h mainwindow.ui) +target_link_libraries(ClassroomTimer PRIVATE Qt${QT_VERSION_MAJOR}::Widgets) +option(BUILD_TEACHING_TESTS "Build teaching project tests" OFF) +if(BUILD_TEACHING_TESTS) + enable_testing() + find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Test) + add_executable(test_ClassroomTimer tests/test_ClassroomTimer.cpp mainwindow.cpp mainwindow.h + countdown.cpp countdown.h mainwindow.ui) + target_include_directories(test_ClassroomTimer PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) + target_link_libraries(test_ClassroomTimer PRIVATE Qt${QT_VERSION_MAJOR}::Widgets Qt${QT_VERSION_MAJOR}::Test) + add_test(NAME ClassroomTimer COMMAND test_ClassroomTimer -platform offscreen) +endif() + diff --git a/Projects/02_ClassroomTimer/ClassroomTimer.pro b/Projects/02_ClassroomTimer/ClassroomTimer.pro new file mode 100644 index 0000000..7b67929 --- /dev/null +++ b/Projects/02_ClassroomTimer/ClassroomTimer.pro @@ -0,0 +1,10 @@ +QT += widgets +CONFIG += c++14 +greaterThan(QT_MAJOR_VERSION, 5): CONFIG += c++17 +TEMPLATE = app +TARGET = ClassroomTimer +SOURCES += main.cpp mainwindow.cpp countdown.cpp +HEADERS += mainwindow.h countdown.h +FORMS += mainwindow.ui +msvc: QMAKE_CXXFLAGS += /utf-8 + diff --git a/Projects/02_ClassroomTimer/README.md b/Projects/02_ClassroomTimer/README.md new file mode 100644 index 0000000..9a4af2b --- /dev/null +++ b/Projects/02_ClassroomTimer/README.md @@ -0,0 +1,65 @@ +# 项目二:课堂计时器 + +适合第3—4章讲解信号槽、定时器、状态变化和数值输入。可用于限时练习、分组讨论与课堂展示。 + +## 功能与操作 + +时长范围为 0 到 23:59:59,但零时长不能开始。默认时长为 5 分钟。 + +- 开始:从设置的时长开始计时。 +- 暂停:保存此刻的剩余时间。 +- 继续:从保存的剩余时间接着计时。 +- 复位:停止本轮计时,并恢复到设置的完整时长。 +- 重新开始:到时后开始新的一轮。 +- 全屏显示:便于投影;按 Esc 退出全屏。 +- 到时提示:显示“时间到”,并可播放一次系统提示音。能否听到提示音取决于系统声音设置。 + +运行中和暂停时,时长输入框均被锁定;先复位,再修改时长。 + +## 课堂任务 + +先连接开始按钮和 QTimer,让学生观察 timeout 信号重复到达。随后故意安排一次较慢的界面处理,讨论“每次 timeout 减 100 毫秒”为什么可能不准确。 + +QTimer 在这个项目中每隔约 100 毫秒请求刷新显示。实际剩余时间由 QElapsedTimer 提供的经过时间计算,不依赖刷新次数。即使某次刷新较晚,下一次仍按实际经过的时间计算。 + +讲解模型时可先使用确定的数值:总时长 10 秒,在第 2.5 秒暂停,还剩 7.5 秒;暂停 1 分钟后继续,剩余时间仍从 7.5 秒开始。 + +## 核心数据 + +Countdown 保存四项信息:完整时长、当前计时片段开始时的剩余量、该片段的开始时刻,以及状态。 + +运行时: +剩余毫秒 = max(0, 片段开始时的剩余毫秒 − 本片段已过去的毫秒)。 + +暂停时先算出剩余毫秒并保存,再切换到 Paused。继续时只记录新的片段开始时刻,不恢复完整时长。 + +界面显示秒数采用向上取整。还剩 1 毫秒时显示 1 秒,真正到时才显示 0,避免“已经显示零但还没结束”的现象。 + +## 状态与操作 + +| 当前状态 | 开始按钮 | 暂停按钮 | 时长输入 | +|---|---|---|---| +| Ready | 开始,零时长除外 | 不可用 | 可修改 | +| Running | 不可用 | 暂停 | 锁定 | +| Paused | 继续 | 不可用 | 锁定 | +| Finished | 重新开始 | 不可用 | 可修改 | + +refreshDisplay 根据同一个状态统一设置按钮,避免在多个槽函数中分别修改后产生矛盾。 + +## 学生练习 + +1. 加入 1、3、5 分钟快捷设置按钮,并遵守运行中不能改变时长的规则。 +2. 最后 10 秒改变数字颜色,到时和复位后恢复正确颜色。 +3. 增加本轮标题,例如“独立练习”。标题变化不应重新开始计时。 + +## 验收用例 + +- 设置 1 秒并开始:到时显示 00:00:00,暂停按钮不可用。 +- 运行时连续触发开始操作:不会重新计算起点。 +- 暂停后等待:剩余时间保持不变;继续后接着减少。 +- 运行或暂停时点击复位:回到原设置时长,并允许修改。 +- 设置零时长:不能开始。 +- 模型两次更新之间跨过截止时间:剩余量直接归零,不出现负数。 + +自动化测试通过传入固定的毫秒数检查计时规则;另有真实按钮测试确认计时模型与界面的连接。 + diff --git a/Projects/02_ClassroomTimer/appearance.h b/Projects/02_ClassroomTimer/appearance.h new file mode 100644 index 0000000..16d3436 --- /dev/null +++ b/Projects/02_ClassroomTimer/appearance.h @@ -0,0 +1,34 @@ +#pragma once +#include +#include +#include + +inline void applyAppearance(QApplication &app) +{ + app.setStyle(QStyleFactory::create(QStringLiteral("Fusion"))); + app.setFont(QFont(QStringLiteral("Microsoft YaHei UI"), 11)); + app.setStyleSheet(QStringLiteral( + "QMainWindow { background: #f5f7fb; }" + "QLabel { color: #23364c; }" + "QLabel#titleLabel { font-size: 27px; font-weight: bold; color: #173b63; }" + "QLabel#subtitleLabel, QLabel#helpLabel { color: #52657a; }" + "QGroupBox { background: white; border: 1px solid #d6e0eb;" + " border-radius: 8px; margin-top: 12px; padding: 18px 12px 12px; }" + "QGroupBox::title { subcontrol-origin: margin; left: 12px; padding: 0 6px; }" + "QLineEdit, QSpinBox, QComboBox { min-height: 32px; padding: 3px 8px; }" + "QLineEdit, QSpinBox, QComboBox, QPlainTextEdit, QListWidget" + " { background: white; color: #23364c; }" + "QPushButton { min-height: 34px; padding: 4px 14px; }" + "QPushButton#convertButton, QPushButton#startButton, QPushButton#drawButton," + " QPushButton#applyButton, QPushButton#groupsButton { background: #255c93;" + " color: white; border: 1px solid #255c93; border-radius: 5px; }" + "QPushButton:disabled, QPushButton#convertButton:disabled," + " QPushButton#startButton:disabled, QPushButton#drawButton:disabled," + " QPushButton#applyButton:disabled, QPushButton#groupsButton:disabled" + " { color: #8995a3; background: #e6ebf1; border-color: #d6e0eb; }" + "QLabel#statusLabel { color: #185376; }" + "QLineEdit#resultEdit { font-size: 23px; min-height: 45px; color: #175e53; }" + "QLabel#timeLabel { font: bold 76px 'Consolas'; color: #173b63; }" + "QProgressBar { border: 1px solid #d6e0eb; border-radius: 6px; height: 14px; }" + "QProgressBar::chunk { background: #2b8a7d; border-radius: 5px; }")); +} diff --git a/Projects/02_ClassroomTimer/countdown.cpp b/Projects/02_ClassroomTimer/countdown.cpp new file mode 100644 index 0000000..f54c323 --- /dev/null +++ b/Projects/02_ClassroomTimer/countdown.cpp @@ -0,0 +1,61 @@ +#include "countdown.h" + +Countdown::Countdown(qint64 durationMs) + : m_duration(qMax(0, durationMs)), m_remainingAtStart(m_duration) +{ +} + +bool Countdown::setDuration(qint64 durationMs) +{ + if (m_state == State::Running || m_state == State::Paused || durationMs < 0) + return false; + m_duration = durationMs; + reset(); + return true; +} + +void Countdown::start(qint64 nowMs) +{ + if (m_state == State::Running || m_duration <= 0) + return; + if (m_state != State::Paused) + m_remainingAtStart = m_duration; + m_segmentStarted = nowMs; + m_state = State::Running; +} + +qint64 Countdown::remaining(qint64 nowMs) const +{ + if (m_state == State::Finished) + return 0; + if (m_state != State::Running) + return m_remainingAtStart; + const qint64 elapsed = qMax(0, nowMs - m_segmentStarted); + return qMax(0, m_remainingAtStart - elapsed); +} + +void Countdown::update(qint64 nowMs) +{ + if (m_state == State::Running && remaining(nowMs) == 0) { + m_remainingAtStart = 0; + m_state = State::Finished; + } +} + +void Countdown::pause(qint64 nowMs) +{ + update(nowMs); + if (m_state != State::Running) + return; + // 先保存这一刻的剩余时间,再切换状态,暂停期间不继续扣减。 + m_remainingAtStart = remaining(nowMs); + m_state = State::Paused; +} + +void Countdown::reset() +{ + m_remainingAtStart = m_duration; + m_segmentStarted = 0; + m_state = State::Ready; +} + diff --git a/Projects/02_ClassroomTimer/countdown.h b/Projects/02_ClassroomTimer/countdown.h new file mode 100644 index 0000000..4a89d7c --- /dev/null +++ b/Projects/02_ClassroomTimer/countdown.h @@ -0,0 +1,23 @@ +#pragma once +#include + +// 界面负责取得当前时间,模型只负责计算;测试可传入确定的毫秒数。 +class Countdown { +public: + enum class State { Ready, Running, Paused, Finished }; + explicit Countdown(qint64 durationMs = 300000); + bool setDuration(qint64 durationMs); + void start(qint64 nowMs); + void pause(qint64 nowMs); + void reset(); + void update(qint64 nowMs); + qint64 remaining(qint64 nowMs) const; + qint64 duration() const { return m_duration; } + State state() const { return m_state; } +private: + qint64 m_duration; + qint64 m_remainingAtStart; + qint64 m_segmentStarted = 0; + State m_state = State::Ready; +}; + diff --git a/Projects/02_ClassroomTimer/main.cpp b/Projects/02_ClassroomTimer/main.cpp new file mode 100644 index 0000000..d8f1ee0 --- /dev/null +++ b/Projects/02_ClassroomTimer/main.cpp @@ -0,0 +1,19 @@ +#include "mainwindow.h" +#include "appearance.h" +#include +#include +#include + +int main(int argc, char *argv[]) +{ +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) + QApplication::setAttribute(Qt::AA_EnableHighDpiScaling); + QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); +#endif + QApplication app(argc, argv); + applyAppearance(app); + MainWindow window; + window.show(); + return app.exec(); +} + diff --git a/Projects/02_ClassroomTimer/mainwindow.cpp b/Projects/02_ClassroomTimer/mainwindow.cpp new file mode 100644 index 0000000..42db7d2 --- /dev/null +++ b/Projects/02_ClassroomTimer/mainwindow.cpp @@ -0,0 +1,91 @@ +#include "mainwindow.h" +#include "ui_mainwindow.h" +#include +#include + +MainWindow::MainWindow(QWidget *parent) + : QMainWindow(parent), ui(new Ui::MainWindow) +{ + ui->setupUi(this); + m_clock.start(); + m_refreshTimer.setInterval(100); + connect(&m_refreshTimer, &QTimer::timeout, this, &MainWindow::refreshDisplay); + for (QSpinBox *spin : {ui->hoursSpin, ui->minutesSpin, ui->secondsSpin}) + connect(spin, static_cast(&QSpinBox::valueChanged), + this, &MainWindow::durationChanged); + connect(ui->startButton, &QPushButton::clicked, this, [this] { + m_countdown.start(m_clock.elapsed()); + refreshDisplay(); + }); + connect(ui->pauseButton, &QPushButton::clicked, this, [this] { + const auto previousState = m_countdown.state(); + m_countdown.pause(m_clock.elapsed()); + if (previousState == Countdown::State::Running + && m_countdown.state() == Countdown::State::Finished + && ui->soundCheck->isChecked()) + QApplication::beep(); + refreshDisplay(); + }); + connect(ui->resetButton, &QPushButton::clicked, this, [this] { + m_countdown.reset(); + refreshDisplay(); + }); + connect(ui->fullscreenButton, &QPushButton::clicked, this, [this] { + if (isFullScreen()) showNormal(); else showFullScreen(); + ui->fullscreenButton->setText(isFullScreen() ? tr("退出全屏") : tr("全屏显示")); + }); + auto *escape = new QShortcut(QKeySequence(Qt::Key_Escape), this); + connect(escape, &QShortcut::activated, this, [this] { + if (isFullScreen()) { + showNormal(); + ui->fullscreenButton->setText(tr("全屏显示")); + } + }); + durationChanged(); +} + +MainWindow::~MainWindow() { delete ui; } + +void MainWindow::durationChanged() +{ + const qint64 seconds = ui->hoursSpin->value() * 3600 + + ui->minutesSpin->value() * 60 + ui->secondsSpin->value(); + m_countdown.setDuration(seconds * 1000); + refreshDisplay(); +} + +void MainWindow::refreshDisplay() +{ + const qint64 now = m_clock.elapsed(); + const auto previousState = m_countdown.state(); + m_countdown.update(now); + const auto state = m_countdown.state(); + const bool running = state == Countdown::State::Running; + const bool paused = state == Countdown::State::Paused; + if (running && !m_refreshTimer.isActive()) m_refreshTimer.start(); + if (!running) m_refreshTimer.stop(); + const qint64 remaining = m_countdown.remaining(now); + // 向上取整:还剩 1 毫秒时显示 1 秒,真正到时才显示零。 + const qint64 seconds = (remaining + 999) / 1000; + ui->timeLabel->setText(QStringLiteral("%1:%2:%3") + .arg(seconds / 3600, 2, 10, QLatin1Char('0')) + .arg((seconds / 60) % 60, 2, 10, QLatin1Char('0')) + .arg(seconds % 60, 2, 10, QLatin1Char('0'))); + ui->progressBar->setValue(m_countdown.duration() == 0 ? 0 + : static_cast(remaining * 1000 / m_countdown.duration())); + ui->durationGroup->setEnabled(!running && !paused); + ui->startButton->setEnabled(!running && m_countdown.duration() > 0); + ui->pauseButton->setEnabled(running); + ui->startButton->setText(paused ? tr("继续") : + state == Countdown::State::Finished ? tr("重新开始") : tr("开始")); + if (running) ui->statusLabel->setText(tr("正在计时")); + else if (paused) ui->statusLabel->setText(tr("已暂停 · 点击“继续”接着计时")); + else if (state == Countdown::State::Finished) + ui->statusLabel->setText(tr("时间到!本轮计时已结束。")); + else ui->statusLabel->setText(m_countdown.duration() > 0 + ? tr("准备就绪 · 点击“开始”") : tr("请先设置大于 0 的时长。")); + if (previousState == Countdown::State::Running && state == Countdown::State::Finished + && ui->soundCheck->isChecked()) + QApplication::beep(); +} + diff --git a/Projects/02_ClassroomTimer/mainwindow.h b/Projects/02_ClassroomTimer/mainwindow.h new file mode 100644 index 0000000..82704b4 --- /dev/null +++ b/Projects/02_ClassroomTimer/mainwindow.h @@ -0,0 +1,21 @@ +#pragma once +#include +#include +#include +#include "countdown.h" +namespace Ui { class MainWindow; } + +class MainWindow : public QMainWindow { + Q_OBJECT +public: + explicit MainWindow(QWidget *parent = nullptr); + ~MainWindow() override; +private: + Ui::MainWindow *ui; + Countdown m_countdown; + QElapsedTimer m_clock; + QTimer m_refreshTimer; + void durationChanged(); + void refreshDisplay(); +}; + diff --git a/Projects/02_ClassroomTimer/mainwindow.ui b/Projects/02_ClassroomTimer/mainwindow.ui new file mode 100644 index 0000000..7252cd0 --- /dev/null +++ b/Projects/02_ClassroomTimer/mainwindow.ui @@ -0,0 +1,242 @@ + + + MainWindow + + + 课堂计时器 + + + + 0 + 0 + 820 + 650 + + + + + + 12 + + + 24 + + + 24 + + + 24 + + + 24 + + + + + 课堂计时器 + + + Qt::PlainText + + + + + + + 用于课堂练习、分组讨论与限时展示。 + + + Qt::PlainText + + + true + + + + + + + 设置时长 + + + + 12 + + + + + 小时 + + + Qt::PlainText + + + + + + + 23 + + + 0 + + + + + + + 分钟 + + + Qt::PlainText + + + + + + + 59 + + + 5 + + + + + + + 秒 + + + Qt::PlainText + + + + + + + 59 + + + 0 + + + + + + + + + + 00:05:00 + + + Qt::PlainText + + + Qt::AlignCenter + + + + 0 + 135 + + + + + + + + 1000 + + + 1000 + + + false + + + + + + + 准备就绪 + + + Qt::PlainText + + + Qt::AlignCenter + + + + 0 + 45 + + + + + + + + 12 + + + + + 开始 + + + + + + + 暂停 + + + + + + + 复位 + + + + + + + 全屏显示 + + + + + + + + + 到时播放系统提示音 + + + true + + + + + + + 计时中和暂停时锁定时长;点击“复位”后可重新设置。全屏时按 Esc 返回。 + + + Qt::PlainText + + + true + + + + + + + + + \ No newline at end of file diff --git a/Projects/02_ClassroomTimer/tests/test_ClassroomTimer.cpp b/Projects/02_ClassroomTimer/tests/test_ClassroomTimer.cpp new file mode 100644 index 0000000..dbafc8f --- /dev/null +++ b/Projects/02_ClassroomTimer/tests/test_ClassroomTimer.cpp @@ -0,0 +1,100 @@ +#include +#include +#include +#include +#include +#include "countdown.h" +#include "mainwindow.h" +#include +#include +#include "appearance.h" + +static void savePreview(QWidget &window, const QString &fileName) +{ + const QString folder = QString::fromLocal8Bit(qgetenv("QT_TEACHING_SCREENSHOTS")); + if (folder.isEmpty()) return; + QDir().mkpath(folder); + window.show(); + QApplication::processEvents(); + QVERIFY(window.grab().save(QDir(folder).filePath(fileName))); +} + +class TimerTest : public QObject { + Q_OBJECT +private slots: + void initTestCase() { applyAppearance(*qApp); } + void pauseResumeAndDrift() + { + Countdown model(10000); + model.start(100); + model.start(500); // 重复开始不能重新计时。 + QCOMPARE(model.remaining(2600), qint64(7500)); + model.pause(2600); + QCOMPARE(model.remaining(90000), qint64(7500)); + QVERIFY(!model.setDuration(2000)); + model.start(100000); + QCOMPARE(model.remaining(102500), qint64(5000)); + model.update(107500); + QVERIFY(model.state() == Countdown::State::Finished); + QCOMPARE(model.remaining(107500), qint64(0)); + model.start(200000); + QCOMPARE(model.remaining(200000), qint64(10000)); + } + void delayedRefreshAndReset() + { + Countdown model(5000); + model.start(0); + model.update(100); + model.update(4300); + QCOMPARE(model.remaining(4300), qint64(700)); + model.update(9999); + QCOMPARE(model.remaining(9999), qint64(0)); + QVERIFY(model.state() == Countdown::State::Finished); + model.reset(); + QVERIFY(model.state() == Countdown::State::Ready); + QCOMPARE(model.remaining(9999), qint64(5000)); + } + void zeroAndDeadlinePause() + { + Countdown model(0); + model.start(0); + QVERIFY(model.state() == Countdown::State::Ready); + QVERIFY(!model.setDuration(-1)); + QVERIFY(model.setDuration(1000)); + model.start(10); + model.pause(1010); + QVERIFY(model.state() == Countdown::State::Finished); + } + void uiWorkflow() + { + MainWindow w; w.show(); + auto *start = w.findChild(QStringLiteral("startButton")); + auto *pause = w.findChild(QStringLiteral("pauseButton")); + auto *reset = w.findChild(QStringLiteral("resetButton")); + auto *minutes = w.findChild(QStringLiteral("minutesSpin")); + auto *seconds = w.findChild(QStringLiteral("secondsSpin")); + auto *time = w.findChild(QStringLiteral("timeLabel")); + w.findChild(QStringLiteral("soundCheck"))->setChecked(false); + savePreview(w, QStringLiteral("02_timer.png")); + minutes->setValue(0); seconds->setValue(1); + QTest::mouseClick(start, Qt::LeftButton); + QVERIFY(!minutes->isEnabled()); + QTest::mouseClick(pause, Qt::LeftButton); + QCOMPARE(start->text(), QStringLiteral("继续")); + const QString pausedText = time->text(); + QTest::qWait(150); + QCOMPARE(time->text(), pausedText); + QTest::mouseClick(start, Qt::LeftButton); + QTRY_COMPARE(time->text(), QStringLiteral("00:00:00")); + QVERIFY(w.findChild(QStringLiteral("statusLabel"))->text().contains(QStringLiteral("时间到"))); + QVERIFY(!pause->isEnabled()); + QTest::mouseClick(reset, Qt::LeftButton); + QCOMPARE(time->text(), QStringLiteral("00:00:01")); + QVERIFY(minutes->isEnabled()); + seconds->setValue(0); + QVERIFY(!start->isEnabled()); + } +}; +QTEST_MAIN(TimerTest) +#include "test_ClassroomTimer.moc" + diff --git a/Projects/02_ClassroomTimer/tests/test_ClassroomTimer.pro b/Projects/02_ClassroomTimer/tests/test_ClassroomTimer.pro new file mode 100644 index 0000000..8be0777 --- /dev/null +++ b/Projects/02_ClassroomTimer/tests/test_ClassroomTimer.pro @@ -0,0 +1,11 @@ +QT += widgets testlib +CONFIG += c++14 console testcase +greaterThan(QT_MAJOR_VERSION, 5): CONFIG += c++17 +TEMPLATE = app +TARGET = test_ClassroomTimer +INCLUDEPATH += .. +SOURCES += test_ClassroomTimer.cpp ../mainwindow.cpp ../countdown.cpp +HEADERS += ../mainwindow.h ../countdown.h +FORMS += ../mainwindow.ui +msvc: QMAKE_CXXFLAGS += /utf-8 + diff --git a/Projects/03_RaffleGroups/CMakeLists.txt b/Projects/03_RaffleGroups/CMakeLists.txt new file mode 100644 index 0000000..b6fa90e --- /dev/null +++ b/Projects/03_RaffleGroups/CMakeLists.txt @@ -0,0 +1,33 @@ +cmake_minimum_required(VERSION 3.16) +project(RaffleGroups VERSION 1.0 LANGUAGES CXX) +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTOUIC ON) +set(CMAKE_CXX_STANDARD 14) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) +find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets) +find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets) +if(QT_VERSION_MAJOR EQUAL 5 AND Qt5Core_VERSION VERSION_LESS 5.14.2) + message(FATAL_ERROR "Qt 5.14.2 or newer is required.") +endif() +if(QT_VERSION_MAJOR EQUAL 6) + set(CMAKE_CXX_STANDARD 17) +endif() +if(MSVC) + add_compile_options(/utf-8) +else() + add_compile_options(-Wall -Wextra -Wpedantic) +endif() +add_executable(RaffleGroups WIN32 main.cpp appearance.h mainwindow.cpp mainwindow.h roster.cpp roster.h mainwindow.ui) +target_link_libraries(RaffleGroups PRIVATE Qt${QT_VERSION_MAJOR}::Widgets) +option(BUILD_TEACHING_TESTS "Build teaching project tests" OFF) +if(BUILD_TEACHING_TESTS) + enable_testing() + find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Test) + add_executable(test_RaffleGroups tests/test_RaffleGroups.cpp mainwindow.cpp mainwindow.h + roster.cpp roster.h mainwindow.ui) + target_include_directories(test_RaffleGroups PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) + target_link_libraries(test_RaffleGroups PRIVATE Qt${QT_VERSION_MAJOR}::Widgets Qt${QT_VERSION_MAJOR}::Test) + add_test(NAME RaffleGroups COMMAND test_RaffleGroups -platform offscreen) +endif() + diff --git a/Projects/03_RaffleGroups/README.md b/Projects/03_RaffleGroups/README.md new file mode 100644 index 0000000..5e937ca --- /dev/null +++ b/Projects/03_RaffleGroups/README.md @@ -0,0 +1,65 @@ +# 项目三:随机抽签与分组工具 + +适合第3—4章讲解 QStringList、QSet、随机数、下拉框和按钮状态。 + +## 名单的含义 + +每行代表一位学生。行首和行尾空白会被去掉,空行会被忽略。相同条目不允许重复;同名学生可以写成“01 张三”和“02 张三”。程序不根据姓名猜测是否为同一个人。 + +打开程序时填入一份虚构的 12 人示例名单,但还没有应用。检查后点击“应用名单”,才能抽签和分组。每次应用都会开始新一轮并清空旧结果。修改名单后,操作按钮暂时禁用,避免操作的实际名单与编辑框不一致。 + +名单上限为 5000 人,每条最多 100 个字符。这个限制用于及时发现错误粘贴,普通班级无需调整。 + +## 不重复抽签 + +选择本次人数后点击“抽取”。程序保存两份列表:完整名单和剩余候选池。抽到一位学生后,立即从候选池中移除,后续抽签只能从剩余的人中选择。 + +本轮全部抽完后,抽取按钮不可用。点击“重置抽签”会重新填满候选池并清除抽签记录;已生成的分组保持不变。 + +课堂上可以先用 A、B、C 三人演示:抽出 B 后候选池只剩 A、C。让学生解释为什么不能每次都从完整名单随机选择。 + +## 随机分组 + +分组始终使用全部已应用名单,与抽签结果无关。 + +有两种参数: + +- 每组最多人数:先用向上取整计算需要几组,再平均分配。 +- 分成几组:直接指定组数,组数不能超过人数。 + +例如 12 人、每组最多 5 人,需要 3 组。为了平衡人数,结果是每组 4 人。这个参数表示人数上限,不要求先装满一组再分下一组。 + +程序先用 Fisher–Yates 算法打乱名单,再按组号轮流分配。每人恰好出现一次,各组人数最多相差 1。再次点击“生成分组”会重新分组,结果不保证与上次不同。 + +## 课堂任务 + +第一步只读名单,使用 QStringList 保存,显示有效人数。再加入空行过滤和重复检查,观察同名但学号不同的两条记录应怎样处理。 + +第二步实现抽签:先抽一人,再抽多人。让学生跟踪 takeAt 执行前后候选池的大小。 + +第三步实现分组。先按原顺序轮流分组,确认没有遗漏,再加入洗牌。把“随机顺序”和“完整分配”分开验证,便于找错。 + +第四步处理界面状态:名单编辑后禁用操作,应用成功后启用,名单重复时保留错误原因。 + +## 学生练习 + +1. 增加“复制本轮抽签记录”按钮。 +2. 保存分组结果到文本文件,作为第8章的延伸任务。 +3. 增加“撤销上一次抽签”,明确如何把人员放回候选池,以及怎样修改历史记录。 + +## 验收用例 + +| 输入或操作 | 预期 | +|---|---| +| 空名单 | 显示提示,不允许开始 | +| A 与前后带空格的 A | 判断重复并指出行号 | +| 01 张三、02 张三 | 作为两位学生接受 | +| 4 人分两次各抽 2 人 | 四人各出现一次,随后不能继续抽 | +| 12 人,每组最多 5 人 | 3 组,每组 4 人 | +| 10 人,分成 3 组 | 人数为 4、3、3,顺序可变 | +| 3 人,要求分成 4 组 | 显示组数过多的提示 | +| 先抽签,再分组 | 分组仍包含全部名单 | +| 已生成结果后编辑名单 | 旧结果清空,重新应用前不能操作 | + +自动化测试用固定种子得到可重复的随机序列,并对 1—100 人的两种分组方式检查总人数、唯一性和组间人数差。界面使用全局随机生成器,正常抽签不使用固定种子。 + diff --git a/Projects/03_RaffleGroups/RaffleGroups.pro b/Projects/03_RaffleGroups/RaffleGroups.pro new file mode 100644 index 0000000..82ca915 --- /dev/null +++ b/Projects/03_RaffleGroups/RaffleGroups.pro @@ -0,0 +1,10 @@ +QT += widgets +CONFIG += c++14 +greaterThan(QT_MAJOR_VERSION, 5): CONFIG += c++17 +TEMPLATE = app +TARGET = RaffleGroups +SOURCES += main.cpp mainwindow.cpp roster.cpp +HEADERS += mainwindow.h roster.h +FORMS += mainwindow.ui +msvc: QMAKE_CXXFLAGS += /utf-8 + diff --git a/Projects/03_RaffleGroups/appearance.h b/Projects/03_RaffleGroups/appearance.h new file mode 100644 index 0000000..16d3436 --- /dev/null +++ b/Projects/03_RaffleGroups/appearance.h @@ -0,0 +1,34 @@ +#pragma once +#include +#include +#include + +inline void applyAppearance(QApplication &app) +{ + app.setStyle(QStyleFactory::create(QStringLiteral("Fusion"))); + app.setFont(QFont(QStringLiteral("Microsoft YaHei UI"), 11)); + app.setStyleSheet(QStringLiteral( + "QMainWindow { background: #f5f7fb; }" + "QLabel { color: #23364c; }" + "QLabel#titleLabel { font-size: 27px; font-weight: bold; color: #173b63; }" + "QLabel#subtitleLabel, QLabel#helpLabel { color: #52657a; }" + "QGroupBox { background: white; border: 1px solid #d6e0eb;" + " border-radius: 8px; margin-top: 12px; padding: 18px 12px 12px; }" + "QGroupBox::title { subcontrol-origin: margin; left: 12px; padding: 0 6px; }" + "QLineEdit, QSpinBox, QComboBox { min-height: 32px; padding: 3px 8px; }" + "QLineEdit, QSpinBox, QComboBox, QPlainTextEdit, QListWidget" + " { background: white; color: #23364c; }" + "QPushButton { min-height: 34px; padding: 4px 14px; }" + "QPushButton#convertButton, QPushButton#startButton, QPushButton#drawButton," + " QPushButton#applyButton, QPushButton#groupsButton { background: #255c93;" + " color: white; border: 1px solid #255c93; border-radius: 5px; }" + "QPushButton:disabled, QPushButton#convertButton:disabled," + " QPushButton#startButton:disabled, QPushButton#drawButton:disabled," + " QPushButton#applyButton:disabled, QPushButton#groupsButton:disabled" + " { color: #8995a3; background: #e6ebf1; border-color: #d6e0eb; }" + "QLabel#statusLabel { color: #185376; }" + "QLineEdit#resultEdit { font-size: 23px; min-height: 45px; color: #175e53; }" + "QLabel#timeLabel { font: bold 76px 'Consolas'; color: #173b63; }" + "QProgressBar { border: 1px solid #d6e0eb; border-radius: 6px; height: 14px; }" + "QProgressBar::chunk { background: #2b8a7d; border-radius: 5px; }")); +} diff --git a/Projects/03_RaffleGroups/main.cpp b/Projects/03_RaffleGroups/main.cpp new file mode 100644 index 0000000..d8f1ee0 --- /dev/null +++ b/Projects/03_RaffleGroups/main.cpp @@ -0,0 +1,19 @@ +#include "mainwindow.h" +#include "appearance.h" +#include +#include +#include + +int main(int argc, char *argv[]) +{ +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) + QApplication::setAttribute(Qt::AA_EnableHighDpiScaling); + QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); +#endif + QApplication app(argc, argv); + applyAppearance(app); + MainWindow window; + window.show(); + return app.exec(); +} + diff --git a/Projects/03_RaffleGroups/mainwindow.cpp b/Projects/03_RaffleGroups/mainwindow.cpp new file mode 100644 index 0000000..3a16f72 --- /dev/null +++ b/Projects/03_RaffleGroups/mainwindow.cpp @@ -0,0 +1,121 @@ +#include "mainwindow.h" +#include "ui_mainwindow.h" +#include +#include + +MainWindow::MainWindow(QWidget *parent) + : QMainWindow(parent), ui(new Ui::MainWindow) +{ + ui->setupUi(this); + ui->groupModeCombo->addItems({tr("每组最多人数"), tr("分成几组")}); + connect(ui->namesEdit, &QPlainTextEdit::textChanged, this, &MainWindow::markDirty); + connect(ui->applyButton, &QPushButton::clicked, this, &MainWindow::applyNames); + connect(ui->sampleButton, &QPushButton::clicked, this, [this] { + ui->namesEdit->setPlainText(QStringLiteral( + "01 陈晨\n02 林悦\n03 王宁\n04 李然\n05 周航\n06 赵晴\n" + "07 孙瑞\n08 吴桐\n09 郑宇\n10 许诺\n11 何欣\n12 方舟")); + }); + connect(ui->drawButton, &QPushButton::clicked, this, &MainWindow::drawNames); + connect(ui->groupsButton, &QPushButton::clicked, this, &MainWindow::makeGroups); + connect(ui->resetButton, &QPushButton::clicked, this, [this] { + m_session.resetDraw(); + m_round = 0; + ui->historyList->clear(); + ui->chosenEdit->clear(); + ui->statusLabel->setText(tr("抽签已重置,所有人重新进入候选池。")); + refreshControls(); + }); + connect(ui->copyGroupsButton, &QPushButton::clicked, this, [this] { + QApplication::clipboard()->setText(ui->groupsEdit->toPlainText()); + ui->statusLabel->setText(tr("分组结果已复制。")); + }); + connect(ui->groupModeCombo, static_cast(&QComboBox::currentIndexChanged), + this, [this] { ui->groupsEdit->clear(); ui->copyGroupsButton->setEnabled(false); }); + connect(ui->groupValueSpin, static_cast(&QSpinBox::valueChanged), + this, [this] { ui->groupsEdit->clear(); ui->copyGroupsButton->setEnabled(false); }); + ui->sampleButton->click(); +} + +MainWindow::~MainWindow() { delete ui; } + +void MainWindow::markDirty() +{ + m_dirty = true; + // 名单有改动时清除旧展示,避免把旧名单的结果当成新名单的结果。 + ui->chosenEdit->clear(); + ui->historyList->clear(); + ui->groupsEdit->clear(); + ui->copyGroupsButton->setEnabled(false); + ui->statusLabel->setText(tr("名单尚未应用。检查后点击“应用名单”开始新一轮。")); + refreshControls(); +} + +void MainWindow::applyNames() +{ + const auto parsed = Roster::parse(ui->namesEdit->toPlainText()); + if (!parsed.ok()) { + ui->statusLabel->setText(parsed.error); + return; + } + m_session.setNames(parsed.names); + m_dirty = false; + m_round = 0; + ui->historyList->clear(); + ui->chosenEdit->clear(); + ui->groupsEdit->clear(); + ui->copyGroupsButton->setEnabled(false); + ui->statusLabel->setText(tr("已应用 %1 人。抽签与分组现在使用这份名单。").arg(parsed.names.size())); + refreshControls(); +} + +void MainWindow::refreshControls() +{ + const int remaining = m_session.remainingCount(); + ui->drawButton->setEnabled(!m_dirty && remaining > 0); + ui->resetButton->setEnabled(!m_dirty); + ui->groupsButton->setEnabled(!m_dirty && !m_session.names().isEmpty()); + ui->drawCountSpin->setEnabled(!m_dirty && remaining > 0); + ui->drawCountSpin->setMaximum(qMax(1, remaining)); + ui->countLabel->setText(m_dirty ? tr("名单待应用") + : tr("名单 %1 人 · 尚未抽到 %2 人").arg(m_session.names().size()).arg(remaining)); +} + +void MainWindow::drawNames() +{ + if (m_dirty) return; + const QStringList selected = m_session.draw(ui->drawCountSpin->value(), + *QRandomGenerator::global()); + if (selected.isEmpty()) return; + ++m_round; + ui->chosenEdit->setPlainText(selected.join(QStringLiteral("\n"))); + ui->historyList->addItem(tr("第 %1 次:%2").arg(m_round).arg(selected.join(QStringLiteral("、")))); + ui->historyList->scrollToBottom(); + ui->statusLabel->setText(m_session.remainingCount() == 0 + ? tr("所有人都已抽到。点击“重置抽签”可以开始下一轮。") + : tr("本次抽取 %1 人,已从候选池中移除。").arg(selected.size())); + refreshControls(); +} + +void MainWindow::makeGroups() +{ + if (m_dirty) return; + const auto groups = m_session.groups(ui->groupValueSpin->value(), + ui->groupModeCombo->currentIndex() == 1, *QRandomGenerator::global()); + if (groups.isEmpty()) { + ui->groupsEdit->clear(); + ui->copyGroupsButton->setEnabled(false); + ui->statusLabel->setText(tr("组数不能超过名单人数,请调整后再分组。")); + return; + } + QStringList lines; + for (int i = 0; i < groups.size(); ++i) { + lines.append(tr("第 %1 组(%2 人)").arg(i + 1).arg(groups.at(i).size())); + lines.append(groups.at(i).join(QStringLiteral("、"))); + lines.append(QString()); + } + ui->groupsEdit->setPlainText(lines.join(QStringLiteral("\n"))); + ui->copyGroupsButton->setEnabled(true); + ui->statusLabel->setText(tr("已将全部 %1 人分为 %2 组,每人出现一次,各组人数最多相差 1。") + .arg(m_session.names().size()).arg(groups.size())); +} + diff --git a/Projects/03_RaffleGroups/mainwindow.h b/Projects/03_RaffleGroups/mainwindow.h new file mode 100644 index 0000000..16f8fd9 --- /dev/null +++ b/Projects/03_RaffleGroups/mainwindow.h @@ -0,0 +1,22 @@ +#pragma once +#include +#include "roster.h" +namespace Ui { class MainWindow; } + +class MainWindow : public QMainWindow { + Q_OBJECT +public: + explicit MainWindow(QWidget *parent = nullptr); + ~MainWindow() override; +private: + Ui::MainWindow *ui; + Roster::Session m_session; + bool m_dirty = true; + int m_round = 0; + void markDirty(); + void applyNames(); + void refreshControls(); + void drawNames(); + void makeGroups(); +}; + diff --git a/Projects/03_RaffleGroups/mainwindow.ui b/Projects/03_RaffleGroups/mainwindow.ui new file mode 100644 index 0000000..fcb8f6e --- /dev/null +++ b/Projects/03_RaffleGroups/mainwindow.ui @@ -0,0 +1,329 @@ + + + MainWindow + + + 随机抽签与分组工具 + + + + 0 + 0 + 1120 + 780 + + + + + + 12 + + + 24 + + + 24 + + + 24 + + + 24 + + + + + 随机抽签与分组 + + + Qt::PlainText + + + + + + + 先应用名单,再抽签或分组。同名学生请使用“学号 姓名”区分。 + + + Qt::PlainText + + + true + + + + + + + 名单待应用 + + + Qt::PlainText + + + + + + + 12 + + + + + 班级名单 + + + + 310 + 0 + + + + + 12 + + + + + 每行一人,空行会被忽略。修改名单后需重新应用。 + + + Qt::PlainText + + + true + + + + + + + 01 张三 +02 李四 + + + + 250 + 320 + + + + + + + + 应用名单(开始新一轮) + + + + + + + 填入示例名单 + + + + + + + + + + + 570 + 0 + + + + + 不重复抽签 + + + + 12 + + + + + 12 + + + + + 本次抽取人数 + + + Qt::PlainText + + + + + + + 1 + + + 5000 + + + + + + + 抽取 + + + + + + + + + 本次抽取 + + + Qt::PlainText + + + + + + + true + + + + 0 + 100 + + + + + 16777215 + 145 + + + + + + + + 本轮抽签记录 + + + Qt::PlainText + + + + + + + + + + 重置抽签 + + + + + + + + 随机分组 + + + + 12 + + + + + 分组使用全部已应用名单,与已抽到哪些人无关。每次点击都会重新分组。 + + + Qt::PlainText + + + true + + + + + + + 12 + + + + + + + + 1 + + + 5000 + + + 4 + + + + + + + + + 生成分组 + + + + + + + true + + + + + + + 复制分组结果 + + + false + + + + + + + + + + + + + + + + Qt::PlainText + + + true + + + + 0 + 55 + + + + + + + + + + \ No newline at end of file diff --git a/Projects/03_RaffleGroups/roster.cpp b/Projects/03_RaffleGroups/roster.cpp new file mode 100644 index 0000000..71ad6c4 --- /dev/null +++ b/Projects/03_RaffleGroups/roster.cpp @@ -0,0 +1,72 @@ +#include "roster.h" +#include + +namespace Roster { +ParsedNames parse(const QString &text) +{ + ParsedNames result; + QSet seen; + const QStringList lines = text.split(QLatin1Char('\n')); + int lineNumber = 0; + for (const QString &line : lines) { + ++lineNumber; + const QString name = line.trimmed(); + if (name.isEmpty()) continue; + if (seen.contains(name)) { + result.error = QStringLiteral("第 %1 行与前面的条目重复:%2。" + "同名学生请加上学号后再应用名单。").arg(lineNumber).arg(name); + return result; + } + if (name.size() > 100) { + result.error = QStringLiteral("第 %1 行超过 100 个字符,请检查是否粘贴了整段文字。") + .arg(lineNumber); + return result; + } + seen.insert(name); + result.names.append(name); + } + if (result.names.isEmpty()) + result.error = QStringLiteral("名单为空,请每行输入一位学生。"); + else if (result.names.size() > 5000) + result.error = QStringLiteral("名单超过 5000 人,请分批操作。"); + return result; +} + +void Session::setNames(const QStringList &names) +{ + m_names = names; + resetDraw(); +} + +void Session::resetDraw() { m_pool = m_names; } + +QStringList Session::draw(int count, QRandomGenerator &random) +{ + QStringList selected; + if (count <= 0 || count > m_pool.size()) return selected; + for (int i = 0; i < count; ++i) { + const int index = random.bounded(static_cast(m_pool.size())); + // 从候选池中移除已抽到的人,本轮后续抽签就不会重复。 + selected.append(m_pool.takeAt(index)); + } + return selected; +} + +QList Session::groups(int value, bool valueIsGroupCount, + QRandomGenerator &random) const +{ + QList result; + const int n = static_cast(m_names.size()); + if (n == 0 || value <= 0 || (valueIsGroupCount && value > n)) return result; + const int count = valueIsGroupCount ? value : (n + value - 1) / value; + QStringList shuffled = m_names; + // Fisher–Yates 洗牌。每次从尚未固定的位置中均匀选取一个。 + for (int i = n - 1; i > 0; --i) + qSwap(shuffled[i], shuffled[random.bounded(i + 1)]); + for (int i = 0; i < count; ++i) result.append(QStringList()); + // 轮流放入各组,保证每人出现一次,各组人数最多相差 1。 + for (int i = 0; i < n; ++i) result[i % count].append(shuffled.at(i)); + return result; +} +} + diff --git a/Projects/03_RaffleGroups/roster.h b/Projects/03_RaffleGroups/roster.h new file mode 100644 index 0000000..da30278 --- /dev/null +++ b/Projects/03_RaffleGroups/roster.h @@ -0,0 +1,28 @@ +#pragma once +#include +#include +#include + +namespace Roster { +struct ParsedNames { + QStringList names; + QString error; + bool ok() const { return error.isEmpty(); } +}; +ParsedNames parse(const QString &text); + +class Session { +public: + void setNames(const QStringList &names); + void resetDraw(); + const QStringList &names() const { return m_names; } + int remainingCount() const { return static_cast(m_pool.size()); } + QStringList draw(int count, QRandomGenerator &random); + QList groups(int value, bool valueIsGroupCount, + QRandomGenerator &random) const; +private: + QStringList m_names; + QStringList m_pool; +}; +} + diff --git a/Projects/03_RaffleGroups/sample_roster.txt b/Projects/03_RaffleGroups/sample_roster.txt new file mode 100644 index 0000000..67d19a7 --- /dev/null +++ b/Projects/03_RaffleGroups/sample_roster.txt @@ -0,0 +1,13 @@ +01 陈晨 +02 林悦 +03 王宁 +04 李然 +05 周航 +06 赵晴 +07 孙瑞 +08 吴桐 +09 郑宇 +10 许诺 +11 何欣 +12 方舟 + diff --git a/Projects/03_RaffleGroups/tests/test_RaffleGroups.cpp b/Projects/03_RaffleGroups/tests/test_RaffleGroups.cpp new file mode 100644 index 0000000..f3cb805 --- /dev/null +++ b/Projects/03_RaffleGroups/tests/test_RaffleGroups.cpp @@ -0,0 +1,119 @@ +#include +#include +#include +#include +#include +#include +#include +#include "roster.h" +#include "mainwindow.h" +#include +#include +#include "appearance.h" + +static void savePreview(QWidget &window, const QString &fileName) +{ + const QString folder = QString::fromLocal8Bit(qgetenv("QT_TEACHING_SCREENSHOTS")); + if (folder.isEmpty()) return; + QDir().mkpath(folder); + window.show(); + QApplication::processEvents(); + QVERIFY(window.grab().save(QDir(folder).filePath(fileName))); +} + +class RaffleTest : public QObject { + Q_OBJECT +private slots: + void initTestCase() { applyAppearance(*qApp); } + void parsing() + { + auto parsed = Roster::parse(QStringLiteral(" 01 张三 \r\n\n02 李四\r\n")); + QVERIFY(parsed.ok()); QCOMPARE(parsed.names.size(), 2); + QCOMPARE(parsed.names.first(), QStringLiteral("01 张三")); + QVERIFY(!Roster::parse(QStringLiteral("张三\n 张三 ")).ok()); + QVERIFY(!Roster::parse(QStringLiteral(" \n ")).ok()); + QVERIFY(Roster::parse(QStringLiteral("01 张三\n02 张三")).ok()); + QVERIFY(!Roster::parse(QString(101, QLatin1Char('x'))).ok()); + } + void drawingWithoutReplacement() + { + Roster::Session session; + const QStringList names = {QStringLiteral("A"), QStringLiteral("B"), + QStringLiteral("C"), QStringLiteral("D")}; + session.setNames(names); + QRandomGenerator random(12345); + QVERIFY(session.draw(5, random).isEmpty()); + QCOMPARE(session.remainingCount(), 4); + QStringList drawn = session.draw(2, random); + drawn.append(session.draw(2, random)); + QSet unique; + for (const QString &name : drawn) unique.insert(name); + QCOMPARE(unique.size(), 4); + QCOMPARE(session.remainingCount(), 0); + QVERIFY(session.draw(1, random).isEmpty()); + session.resetDraw(); + QCOMPARE(session.remainingCount(), 4); + } + void groupingInvariants() + { + QRandomGenerator random(54321); + for (int n = 1; n <= 100; ++n) { + QStringList names; + for (int i = 0; i < n; ++i) names.append(QString::number(i)); + Roster::Session session; session.setNames(names); + session.draw(1, random); // 分组仍使用全部名单。 + for (bool byCount : {false, true}) { + const int value = byCount ? qMin(n, 7) : 7; + const auto groups = session.groups(value, byCount, random); + QCOMPARE(groups.size(), byCount ? value : (n + value - 1) / value); + QSet all; int total = 0, smallest = n, largest = 0; + for (const QStringList &group : groups) { + QVERIFY(!group.isEmpty()); + smallest = qMin(smallest, static_cast(group.size())); + largest = qMax(largest, static_cast(group.size())); + total += static_cast(group.size()); + for (const QString &name : group) all.insert(name); + } + QCOMPARE(total, n); QCOMPARE(all.size(), n); + QVERIFY(largest - smallest <= 1); + if (!byCount) QVERIFY(largest <= value); + } + QVERIFY(session.groups(n + 1, true, random).isEmpty()); + } + } + void uiWorkflow() + { + MainWindow w; w.show(); + auto *names = w.findChild(QStringLiteral("namesEdit")); + auto *apply = w.findChild(QStringLiteral("applyButton")); + auto *draw = w.findChild(QStringLiteral("drawButton")); + auto *chosen = w.findChild(QStringLiteral("chosenEdit")); + QVERIFY(!draw->isEnabled()); + QTest::mouseClick(apply, Qt::LeftButton); + QVERIFY(draw->isEnabled()); + QTest::mouseClick(draw, Qt::LeftButton); + QVERIFY(!chosen->toPlainText().isEmpty()); + savePreview(w, QStringLiteral("03_raffle.png")); + w.findChild(QStringLiteral("resultTabs"))->setCurrentIndex(1); + QTest::mouseClick(w.findChild(QStringLiteral("groupsButton")), Qt::LeftButton); + auto *groups = w.findChild(QStringLiteral("groupsEdit")); + QVERIFY(groups->toPlainText().contains(QStringLiteral("第 3 组"))); + savePreview(w, QStringLiteral("03_groups.png")); + names->setPlainText(QStringLiteral("A\nA")); + QVERIFY(!draw->isEnabled()); + QVERIFY(groups->toPlainText().isEmpty()); + QTest::mouseClick(apply, Qt::LeftButton); + QVERIFY(w.findChild(QStringLiteral("statusLabel"))->text().contains(QStringLiteral("重复"))); + names->setPlainText(QStringLiteral("A\nB")); + QTest::mouseClick(apply, Qt::LeftButton); + w.findChild(QStringLiteral("resultTabs"))->setCurrentIndex(0); + w.findChild(QStringLiteral("drawCountSpin"))->setValue(2); + QTest::mouseClick(draw, Qt::LeftButton); + QVERIFY(!draw->isEnabled()); + QTest::mouseClick(w.findChild(QStringLiteral("resetButton")), Qt::LeftButton); + QVERIFY(draw->isEnabled()); + } +}; +QTEST_MAIN(RaffleTest) +#include "test_RaffleGroups.moc" + diff --git a/Projects/03_RaffleGroups/tests/test_RaffleGroups.pro b/Projects/03_RaffleGroups/tests/test_RaffleGroups.pro new file mode 100644 index 0000000..5eb13fe --- /dev/null +++ b/Projects/03_RaffleGroups/tests/test_RaffleGroups.pro @@ -0,0 +1,11 @@ +QT += widgets testlib +CONFIG += c++14 console testcase +greaterThan(QT_MAJOR_VERSION, 5): CONFIG += c++17 +TEMPLATE = app +TARGET = test_RaffleGroups +INCLUDEPATH += .. +SOURCES += test_RaffleGroups.cpp ../mainwindow.cpp ../roster.cpp +HEADERS += ../mainwindow.h ../roster.h +FORMS += ../mainwindow.ui +msvc: QMAKE_CXXFLAGS += /utf-8 + diff --git a/Projects/CMakeLists.txt b/Projects/CMakeLists.txt new file mode 100644 index 0000000..d61d2ba --- /dev/null +++ b/Projects/CMakeLists.txt @@ -0,0 +1,10 @@ +cmake_minimum_required(VERSION 3.16) +project(QtTeachingProjects LANGUAGES CXX) +option(BUILD_TEACHING_TESTS "Build all regression tests" OFF) +if(BUILD_TEACHING_TESTS) + enable_testing() +endif() +add_subdirectory(01_UnitConverter) +add_subdirectory(02_ClassroomTimer) +add_subdirectory(03_RaffleGroups) + diff --git a/Projects/QtTeachingProjects.pro b/Projects/QtTeachingProjects.pro new file mode 100644 index 0000000..877a3f8 --- /dev/null +++ b/Projects/QtTeachingProjects.pro @@ -0,0 +1,6 @@ +TEMPLATE = subdirs +SUBDIRS = converter timer raffle +converter.file = 01_UnitConverter/UnitConverter.pro +timer.file = 02_ClassroomTimer/ClassroomTimer.pro +raffle.file = 03_RaffleGroups/RaffleGroups.pro + diff --git a/Projects/README.md b/Projects/README.md new file mode 100644 index 0000000..c7e811a --- /dev/null +++ b/Projects/README.md @@ -0,0 +1,74 @@ +# Qt Widgets 前期教学项目 + +三个独立的 C++ 桌面项目,对应单位换算、课堂计时、随机抽签与分组。全部使用 Qt Widgets,界面文件为 Qt Designer 的 `.ui`,没有 QML、Qt Quick 或网页界面。 + +## 项目入口 + +| 项目 | Qt Creator 入口 | 教学说明 | +|---|---|---| +| 单位换算器 | `01_UnitConverter/UnitConverter.pro` | `01_UnitConverter/README.md` | +| 课堂计时器 | `02_ClassroomTimer/ClassroomTimer.pro` | `02_ClassroomTimer/README.md` | +| 随机抽签与分组 | `03_RaffleGroups/RaffleGroups.pro` | `03_RaffleGroups/README.md` | + +每个项目也有独立的 `CMakeLists.txt`。根目录的 `QtTeachingProjects.pro` 和 `CMakeLists.txt` 可以一次打开三个项目。目录使用英文,便于旧版 Windows 构建工具处理路径;界面、注释和教学说明使用中文。 + +## 先运行,再阅读源码 + +`Run_Qt5.14.2` 中的三个 EXE 是 Windows 64 位演示程序,附带运行库,可直接双击。转交其他电脑时请复制整个目录。 + +- `UnitConverter.exe`:单位换算器。 +- `ClassroomTimer.exe`:课堂计时器。 +- `RaffleGroups.exe`:随机抽签与分组。 + +## 用 Qt Creator 打开 + +1. 选择“文件 → 打开文件或项目”,打开上述任意一个 `.pro`。 +2. 选择桌面 Kit。本机已经配置的 `Desktop Qt 6.8.3 MinGW 64-bit` 可以使用。 +3. 构建并运行。构建目录建议使用英文路径,并与源码目录分开。 +4. 双击 `mainwindow.ui` 可进入 Designer,修改布局和组件属性。 +5. 换用 Qt 5.14.2 时,选择对应的 Qt 5.14.2 桌面 Kit,并使用新的构建目录。Qt 库与编译器必须属于匹配的 Kit,不能混用 MinGW 与 MSVC。 + +源码以 Qt 5.14.2 为最低版本。Qt 5 构建使用 C++14;Qt 6 构建自动使用 C++17。没有使用 Qt 6 专有的控件接口,也没有要求 Qt 5.15 的无版本 CMake 目标。 + +## 怎样阅读 + +每个项目都按下面的顺序阅读: + +1. `mainwindow.ui`:先认清组件名称与布局。 +2. `main.cpp`:创建应用、应用外观、显示主窗口、进入事件循环。 +3. `mainwindow.cpp`:找出信号连接,再追踪一次按钮操作。 +4. `conversion.cpp` / `countdown.cpp` / `roster.cpp`:阅读不依赖具体控件的计算规则。 +5. `tests`:查看正常输入和边界情况应得到什么结果。 + +`appearance.h` 只负责字体与样式,可以在学生掌握功能后再讲。业务逻辑没有依赖这些样式。当前交付的是可运行的完整参考工程,学生练习见各项目 README。 + +## CMake 构建 + +以 Qt 5.14.2 的 MinGW Kit 为例,先将匹配的编译器、Qt 的 bin 和 Ninja 加入当前终端 PATH,再运行: + +```powershell +cmake -S . -B build-qt5 -G Ninja -DCMAKE_PREFIX_PATH="D:/Qt/5.14.2/mingw73_64" -DCMAKE_BUILD_TYPE=Release +cmake --build build-qt5 +``` + +示例中的 Qt 路径需要替换成实际安装位置。本机 Qt 6 的前缀为 `D:/Qt/6.8.3/mingw_64`,编译器位于 `D:/Qt/Tools/mingw1310_64/bin`。旧版本 Qt Creator 可直接使用 qmake 工程,不必额外配置 CMake。 + +## 自动化验证 + +测试需要同一套 Qt 中的 Qt Test 模块。普通构建默认不编译测试: + +```powershell +cmake -S . -B build-test -G Ninja -DCMAKE_PREFIX_PATH="你的Qt目录" -DBUILD_TEACHING_TESTS=ON -DCMAKE_BUILD_TYPE=Release +cmake --build build-test +ctest --test-dir build-test --output-on-failure +``` + +也可打开各项目 `tests` 中的 `.pro` 独立运行测试。测试在后台使用 offscreen 平台,不打开浏览器。Windows 上如需保存包含中文的后台截图,可设置: + +```powershell +$env:QT_QPA_FONTDIR = "C:/Windows/Fonts" +$env:QT_TEACHING_SCREENSHOTS = "D:/QtTeachingScreenshots" +``` + +测试覆盖换算公式、非法输入、暂停与继续、延迟刷新、不重复抽签、分组完整性,以及主要按钮操作。具体版本、编译器和结果见 `verification/验证说明.md`。 + diff --git a/Projects/Run_Qt5.14.2/ClassroomTimer.exe b/Projects/Run_Qt5.14.2/ClassroomTimer.exe new file mode 100644 index 0000000..614f80b Binary files /dev/null and b/Projects/Run_Qt5.14.2/ClassroomTimer.exe differ diff --git a/Projects/Run_Qt5.14.2/Qt5Core.dll b/Projects/Run_Qt5.14.2/Qt5Core.dll new file mode 100644 index 0000000..5ec58e1 Binary files /dev/null and b/Projects/Run_Qt5.14.2/Qt5Core.dll differ diff --git a/Projects/Run_Qt5.14.2/Qt5Gui.dll b/Projects/Run_Qt5.14.2/Qt5Gui.dll new file mode 100644 index 0000000..d75c183 Binary files /dev/null and b/Projects/Run_Qt5.14.2/Qt5Gui.dll differ diff --git a/Projects/Run_Qt5.14.2/Qt5Widgets.dll b/Projects/Run_Qt5.14.2/Qt5Widgets.dll new file mode 100644 index 0000000..84511cc Binary files /dev/null and b/Projects/Run_Qt5.14.2/Qt5Widgets.dll differ diff --git a/Projects/Run_Qt5.14.2/RaffleGroups.exe b/Projects/Run_Qt5.14.2/RaffleGroups.exe new file mode 100644 index 0000000..1d6873d Binary files /dev/null and b/Projects/Run_Qt5.14.2/RaffleGroups.exe differ diff --git a/Projects/Run_Qt5.14.2/UnitConverter.exe b/Projects/Run_Qt5.14.2/UnitConverter.exe new file mode 100644 index 0000000..a892b0f Binary files /dev/null and b/Projects/Run_Qt5.14.2/UnitConverter.exe differ diff --git a/Projects/Run_Qt5.14.2/libgcc_s_seh-1.dll b/Projects/Run_Qt5.14.2/libgcc_s_seh-1.dll new file mode 100644 index 0000000..4ec945b Binary files /dev/null and b/Projects/Run_Qt5.14.2/libgcc_s_seh-1.dll differ diff --git a/Projects/Run_Qt5.14.2/libstdc++-6.dll b/Projects/Run_Qt5.14.2/libstdc++-6.dll new file mode 100644 index 0000000..8e55acc Binary files /dev/null and b/Projects/Run_Qt5.14.2/libstdc++-6.dll differ diff --git a/Projects/Run_Qt5.14.2/libwinpthread-1.dll b/Projects/Run_Qt5.14.2/libwinpthread-1.dll new file mode 100644 index 0000000..d9f4e1a Binary files /dev/null and b/Projects/Run_Qt5.14.2/libwinpthread-1.dll differ diff --git a/Projects/Run_Qt5.14.2/licenses/GCC-GPL-3.txt b/Projects/Run_Qt5.14.2/licenses/GCC-GPL-3.txt new file mode 100644 index 0000000..94a9ed0 --- /dev/null +++ b/Projects/Run_Qt5.14.2/licenses/GCC-GPL-3.txt @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/Projects/Run_Qt5.14.2/licenses/GCC-Runtime-Exception.txt b/Projects/Run_Qt5.14.2/licenses/GCC-Runtime-Exception.txt new file mode 100644 index 0000000..e1b3c69 --- /dev/null +++ b/Projects/Run_Qt5.14.2/licenses/GCC-Runtime-Exception.txt @@ -0,0 +1,73 @@ +GCC RUNTIME LIBRARY EXCEPTION + +Version 3.1, 31 March 2009 + +Copyright (C) 2009 Free Software Foundation, Inc. + +Everyone is permitted to copy and distribute verbatim copies of this +license document, but changing it is not allowed. + +This GCC Runtime Library Exception ("Exception") is an additional +permission under section 7 of the GNU General Public License, version +3 ("GPLv3"). It applies to a given file (the "Runtime Library") that +bears a notice placed by the copyright holder of the file stating that +the file is governed by GPLv3 along with this Exception. + +When you use GCC to compile a program, GCC may combine portions of +certain GCC header files and runtime libraries with the compiled +program. The purpose of this Exception is to allow compilation of +non-GPL (including proprietary) programs to use, in this way, the +header files and runtime libraries covered by this Exception. + +0. Definitions. + +A file is an "Independent Module" if it either requires the Runtime +Library for execution after a Compilation Process, or makes use of an +interface provided by the Runtime Library, but is not otherwise based +on the Runtime Library. + +"GCC" means a version of the GNU Compiler Collection, with or without +modifications, governed by version 3 (or a specified later version) of +the GNU General Public License (GPL) with the option of using any +subsequent versions published by the FSF. + +"GPL-compatible Software" is software whose conditions of propagation, +modification and use would permit combination with GCC in accord with +the license of GCC. + +"Target Code" refers to output from any compiler for a real or virtual +target processor architecture, in executable form or suitable for +input to an assembler, loader, linker and/or execution +phase. Notwithstanding that, Target Code does not include data in any +format that is used as a compiler intermediate representation, or used +for producing a compiler intermediate representation. + +The "Compilation Process" transforms code entirely represented in +non-intermediate languages designed for human-written code, and/or in +Java Virtual Machine byte code, into Target Code. Thus, for example, +use of source code generators and preprocessors need not be considered +part of the Compilation Process, since the Compilation Process can be +understood as starting with the output of the generators or +preprocessors. + +A Compilation Process is "Eligible" if it is done using GCC, alone or +with other GPL-compatible software, or if it is done without using any +work based on GCC. For example, using non-GPL-compatible Software to +optimize any GCC intermediate representations would not qualify as an +Eligible Compilation Process. + +1. Grant of Additional Permission. + +You have permission to propagate a work of Target Code formed by +combining the Runtime Library with Independent Modules, even if such +propagation would otherwise violate the terms of GPLv3, provided that +all Target Code was generated by Eligible Compilation Processes. You +may then convey such a combination under terms of your choice, +consistent with the licensing of the Independent Modules. + +2. No Weakening of GCC Copyleft. + +The availability of this Exception does not imply any general +presumption that third-party software is unaffected by the copyleft +requirements of the license of GCC. + diff --git a/Projects/Run_Qt5.14.2/licenses/MinGW-runtime.txt b/Projects/Run_Qt5.14.2/licenses/MinGW-runtime.txt new file mode 100644 index 0000000..3d11e87 --- /dev/null +++ b/Projects/Run_Qt5.14.2/licenses/MinGW-runtime.txt @@ -0,0 +1,240 @@ +MinGW-w64 runtime licensing +*************************** + +This program or library was built using MinGW-w64 and statically +linked against the MinGW-w64 runtime. Some parts of the runtime +are under licenses which require that the copyright and license +notices are included when distributing the code in binary form. +These notices are listed below. + + +======================== +Overall copyright notice +======================== + +Copyright (c) 2009, 2010 by the mingw-w64 project + +This license has been certified as open source. It has also been designated +as GPL compatible by the Free Software Foundation (FSF). + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions in source code must retain the accompanying copyright + notice, this list of conditions, and the following disclaimer. + 2. Redistributions in binary form must reproduce the accompanying + copyright notice, this list of conditions, and the following disclaimer + in the documentation and/or other materials provided with the + distribution. + 3. Names of the copyright holders must not be used to endorse or promote + products derived from this software without prior written permission + from the copyright holders. + 4. The right to distribute this software or to use it for any purpose does + not give you the right to use Servicemarks (sm) or Trademarks (tm) of + the copyright holders. Use of them is covered by separate agreement + with the copyright holders. + 5. If any files are modified, you must cause the modified files to carry + prominent notices stating that you changed the files and the date of + any change. + +Disclaimer + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY EXPRESSED +OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +======================================== +getopt, getopt_long, and getop_long_only +======================================== + +Copyright (c) 2002 Todd C. Miller + +Permission to use, copy, modify, and distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +Sponsored in part by the Defense Advanced Research Projects +Agency (DARPA) and Air Force Research Laboratory, Air Force +Materiel Command, USAF, under agreement number F39502-99-1-0512. + + * * * * * * * + +Copyright (c) 2000 The NetBSD Foundation, Inc. +All rights reserved. + +This code is derived from software contributed to The NetBSD Foundation +by Dieter Baron and Thomas Klausner. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + + +=============================================================== +gdtoa: Converting between IEEE floating point numbers and ASCII +=============================================================== + +The author of this software is David M. Gay. + +Copyright (C) 1997, 1998, 1999, 2000, 2001 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER +IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +THIS SOFTWARE. + + * * * * * * * + +The author of this software is David M. Gay. + +Copyright (C) 2005 by David M. Gay +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that the copyright notice and this permission notice and warranty +disclaimer appear in supporting documentation, and that the name of +the author or any of his current or former employers not be used in +advertising or publicity pertaining to distribution of the software +without specific, written prior permission. + +THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN +NO EVENT SHALL THE AUTHOR OR ANY OF HIS CURRENT OR FORMER EMPLOYERS BE +LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY +DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + + * * * * * * * + +The author of this software is David M. Gay. + +Copyright (C) 2004 by David M. Gay. +All Rights Reserved +Based on material in the rest of /netlib/fp/gdota.tar.gz, +which is copyright (C) 1998, 2000 by Lucent Technologies. + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER +IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +THIS SOFTWARE. + + +========================= +Parts of the math library +========================= + +Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + +Developed at SunSoft, a Sun Microsystems, Inc. business. +Permission to use, copy, modify, and distribute this +software is freely granted, provided that this notice +is preserved. + + * * * * * * * + +Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + +Developed at SunPro, a Sun Microsystems, Inc. business. +Permission to use, copy, modify, and distribute this +software is freely granted, provided that this notice +is preserved. + + * * * * * * * + +FIXME: Cephes math lib +Copyright (C) 1984-1998 Stephen L. Moshier + +It sounds vague, but as to be found at +, it gives an +impression that the author could be willing to give an explicit +permission to distribute those files e.g. under a BSD style license. So +probably there is no problem here, although it could be good to get a +permission from the author and then add a license into the Cephes files +in MinGW runtime. At least on follow-up it is marked that debian sees the +version a-like BSD one. As MinGW.org (where those cephes parts are coming +from) distributes them now over 6 years, it should be fine. + +=================================== +Headers and IDLs imported from Wine +=================================== + +Some header and IDL files were imported from the Wine project. These files +are prominent maked in source. Their copyright belongs to contributors and +they are distributed under LGPL license. + +Disclaimer + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. diff --git a/Projects/Run_Qt5.14.2/licenses/Qt-GPL-3.txt b/Projects/Run_Qt5.14.2/licenses/Qt-GPL-3.txt new file mode 100644 index 0000000..94a9ed0 --- /dev/null +++ b/Projects/Run_Qt5.14.2/licenses/Qt-GPL-3.txt @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/Projects/Run_Qt5.14.2/licenses/Qt-LGPL-3.txt b/Projects/Run_Qt5.14.2/licenses/Qt-LGPL-3.txt new file mode 100644 index 0000000..65c5ca8 --- /dev/null +++ b/Projects/Run_Qt5.14.2/licenses/Qt-LGPL-3.txt @@ -0,0 +1,165 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. diff --git a/Projects/Run_Qt5.14.2/licenses/winpthreads.txt b/Projects/Run_Qt5.14.2/licenses/winpthreads.txt new file mode 100644 index 0000000..3507701 --- /dev/null +++ b/Projects/Run_Qt5.14.2/licenses/winpthreads.txt @@ -0,0 +1,57 @@ +Copyright (c) 2011 mingw-w64 project + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + + +/* + * Parts of this library are derived by: + * + * Posix Threads library for Microsoft Windows + * + * Use at own risk, there is no implied warranty to this code. + * It uses undocumented features of Microsoft Windows that can change + * at any time in the future. + * + * (C) 2010 Lockless Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * * Neither the name of Lockless Inc. nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AN + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ diff --git a/Projects/Run_Qt5.14.2/licenses/第三方组件说明.txt b/Projects/Run_Qt5.14.2/licenses/第三方组件说明.txt new file mode 100644 index 0000000..5bf9977 --- /dev/null +++ b/Projects/Run_Qt5.14.2/licenses/第三方组件说明.txt @@ -0,0 +1,9 @@ +演示程序动态链接 Qt 5.14.2 的 Qt Core、Qt Gui 和 Qt Widgets,并附带 Windows 平台插件。 +Qt 著作权属于 The Qt Company 及相应贡献者。 +Qt 源码与版本信息:https://download.qt.io/archive/qt/5.14/5.14.2/ +Qt Base 对应源码:https://code.qt.io/cgit/qt/qtbase.git/tree/?h=v5.14.2 + +本目录保留 GNU LGPL v3、GNU GPL v3、GCC 运行库例外,以及 MinGW / winpthreads 的相关许可文本。 +GNU 标准许可文本取自本机 Qt 源码的 LICENSES 目录;MinGW 相关文本取自匹配的 MinGW 7.3 工具链。 +项目源代码和重新构建方法位于上一级 Projects 目录的三个工程与 README 中。 + diff --git a/Projects/Run_Qt5.14.2/platforms/qwindows.dll b/Projects/Run_Qt5.14.2/platforms/qwindows.dll new file mode 100644 index 0000000..b02c018 Binary files /dev/null and b/Projects/Run_Qt5.14.2/platforms/qwindows.dll differ diff --git a/Projects/Run_Qt5.14.2/qt.conf b/Projects/Run_Qt5.14.2/qt.conf new file mode 100644 index 0000000..f783bdb --- /dev/null +++ b/Projects/Run_Qt5.14.2/qt.conf @@ -0,0 +1,3 @@ +[Paths] +Prefix=. +Plugins=. diff --git a/Projects/Run_Qt5.14.2/使用说明.txt b/Projects/Run_Qt5.14.2/使用说明.txt new file mode 100644 index 0000000..0204635 --- /dev/null +++ b/Projects/Run_Qt5.14.2/使用说明.txt @@ -0,0 +1,8 @@ +直接双击以下程序: +UnitConverter.exe:单位换算器 +ClassroomTimer.exe:课堂计时器 +RaffleGroups.exe:随机抽签与分组工具 + +这些演示程序使用 Qt 5.14.2,适用于 Windows 64 位。 +复制到其他位置时,请复制整个文件夹,保留 DLL、qt.conf 和 platforms 文件夹。 +对应源码、Qt Creator 工程和教学说明位于上一级目录的三个项目文件夹。 diff --git a/Projects/verification/files_sha256.json b/Projects/verification/files_sha256.json new file mode 100644 index 0000000..f43248d --- /dev/null +++ b/Projects/verification/files_sha256.json @@ -0,0 +1,367 @@ +[ + { + "Path": ".gitignore", + "Bytes": 46, + "SHA256": "729579E4DDF0ED47CAB70376FAB0D0501FF1F5C5D7AC50C70293E6FAF37619DB" + }, + { + "Path": "CMakeLists.txt", + "Bytes": 301, + "SHA256": "6B4F65FFF7DB117DCBB402A84ECACA1CBE9F4DB78244502C8F5AB34739A1AF82" + }, + { + "Path": "QtTeachingProjects.pro", + "Bytes": 202, + "SHA256": "1B1CC3F473A2A279B34FBDC764D6792B69431CBEB412D9C6DDB95D4D02A27451" + }, + { + "Path": "README.md", + "Bytes": 3925, + "SHA256": "C0EFDA0486386EEE2E59CDEA1C12F95BAA65A5929AC77D20D69319D925E2AA55" + }, + { + "Path": "01_UnitConverter\\appearance.h", + "Bytes": 1987, + "SHA256": "108BE9DB48929BA793DEDF15C50EFCCA076DE011E05E2924709431F70D10D764" + }, + { + "Path": "01_UnitConverter\\CMakeLists.txt", + "Bytes": 1514, + "SHA256": "69120A897E875DF8DF135077555B215BCDB328D8700E66285443A034C1E35226" + }, + { + "Path": "01_UnitConverter\\conversion.cpp", + "Bytes": 4036, + "SHA256": "8AE070A1C7E746E463C630CDF41B0CAC27CE5B4F70071FC167AA2531385A024A" + }, + { + "Path": "01_UnitConverter\\conversion.h", + "Bytes": 349, + "SHA256": "31E3B464E78D126C4664DCAC9918D39E5ABEE8CFFE8BB5823C36771CF06BC387" + }, + { + "Path": "01_UnitConverter\\main.cpp", + "Bytes": 466, + "SHA256": "EA31C353F95B264D131797B862378693C8FBD1CEE97B97ADE143BA8EEBFB1319" + }, + { + "Path": "01_UnitConverter\\mainwindow.cpp", + "Bytes": 3384, + "SHA256": "31794F8B3CE67449674C0DE610E93CAA2916D73BA6F2FD5E6B7A4819FED67BFD" + }, + { + "Path": "01_UnitConverter\\mainwindow.h", + "Bytes": 326, + "SHA256": "CC7515940619ACB6C103867B4C78160335CEDE2E4DCFCE5FD8F21D2A8A070EE7" + }, + { + "Path": "01_UnitConverter\\mainwindow.ui", + "Bytes": 7072, + "SHA256": "9CC4D08B107D74C50C857B14C12CCDF93F1FEA2C2DDA0104E31CAB812D3F4AF1" + }, + { + "Path": "01_UnitConverter\\README.md", + "Bytes": 3198, + "SHA256": "EF3E361F701F54B109569BFC46E22555EC234DBD084FFA137225521C0F167F26" + }, + { + "Path": "01_UnitConverter\\UnitConverter.pro", + "Bytes": 260, + "SHA256": "1B193678D6BA461157590E3A004C44C2494B508DE7A0899A8DB93E152714DC94" + }, + { + "Path": "01_UnitConverter\\tests\\test_UnitConverter.cpp", + "Bytes": 4460, + "SHA256": "6C6AF6A13F7D90DFFD667760ED66F7370505B1027F33C8D798A389F00E169370" + }, + { + "Path": "01_UnitConverter\\tests\\test_UnitConverter.pro", + "Bytes": 337, + "SHA256": "8CA1B47AF0C2449B3E810C34C3C0796632BF08887D7C165A1921EC48E4AB8FAF" + }, + { + "Path": "02_ClassroomTimer\\appearance.h", + "Bytes": 1987, + "SHA256": "108BE9DB48929BA793DEDF15C50EFCCA076DE011E05E2924709431F70D10D764" + }, + { + "Path": "02_ClassroomTimer\\ClassroomTimer.pro", + "Bytes": 259, + "SHA256": "9544F5A3EFF1109DE3CF3A22E6C0B38AB99C52C234A2B49F76EBC85B19F4BDA7" + }, + { + "Path": "02_ClassroomTimer\\CMakeLists.txt", + "Bytes": 1519, + "SHA256": "1CB8393F4737A3A76BC177F597E85DF2AFFE3B8B52274AEC94C6F91EA12FFD1D" + }, + { + "Path": "02_ClassroomTimer\\countdown.cpp", + "Bytes": 1484, + "SHA256": "FD74A24071882025F4DCDD4AD2E4D8EE230680228C53E31A8F9A49982E155936" + }, + { + "Path": "02_ClassroomTimer\\countdown.h", + "Bytes": 689, + "SHA256": "617004850F4157BCD29DC631D7A0EA6FD9CF287A9B8CDB9BB8C1251D0DF6A129" + }, + { + "Path": "02_ClassroomTimer\\main.cpp", + "Bytes": 466, + "SHA256": "EA31C353F95B264D131797B862378693C8FBD1CEE97B97ADE143BA8EEBFB1319" + }, + { + "Path": "02_ClassroomTimer\\mainwindow.cpp", + "Bytes": 3962, + "SHA256": "7D5CE3593957D8808794045AEDA16FEE740EDFE67024C11FD08632509D9CF9B9" + }, + { + "Path": "02_ClassroomTimer\\mainwindow.h", + "Bytes": 452, + "SHA256": "79AFDE69E2110147E1565388A25D9E65EFE1AF97900613CA50F6762232EC17C2" + }, + { + "Path": "02_ClassroomTimer\\mainwindow.ui", + "Bytes": 6743, + "SHA256": "4494EDD52C5ECA186F38BA567FD7E21697E8BCC7E0F78811CD00656E0D24B1BE" + }, + { + "Path": "02_ClassroomTimer\\README.md", + "Bytes": 3214, + "SHA256": "FC7046ADCBC50F464C5C1A085FDEB0D1B25C20749B31FD7397985F2C3EC5AAF4" + }, + { + "Path": "02_ClassroomTimer\\tests\\test_ClassroomTimer.cpp", + "Bytes": 3770, + "SHA256": "0B68CE3D132361E0699C6375993908D39ECC741AA506EECB605676B93A1D9ECC" + }, + { + "Path": "02_ClassroomTimer\\tests\\test_ClassroomTimer.pro", + "Bytes": 337, + "SHA256": "14D37177C38258C5241332BFA61BC1860C4F169540E869C87D47B3770D941581" + }, + { + "Path": "03_RaffleGroups\\appearance.h", + "Bytes": 1987, + "SHA256": "108BE9DB48929BA793DEDF15C50EFCCA076DE011E05E2924709431F70D10D764" + }, + { + "Path": "03_RaffleGroups\\CMakeLists.txt", + "Bytes": 1489, + "SHA256": "77F4C5021B5C01906959DF7914DC369FA996BDD9E4496EFD84ECF69BED8022D2" + }, + { + "Path": "03_RaffleGroups\\main.cpp", + "Bytes": 466, + "SHA256": "EA31C353F95B264D131797B862378693C8FBD1CEE97B97ADE143BA8EEBFB1319" + }, + { + "Path": "03_RaffleGroups\\mainwindow.cpp", + "Bytes": 5210, + "SHA256": "A6441794ED93E60E5D3844C01D738BEC684D0D82C0A56D48C81137150549649D" + }, + { + "Path": "03_RaffleGroups\\mainwindow.h", + "Bytes": 465, + "SHA256": "D39048178C9074C0D619E2154881BDDE60F50EFFBD914E488D7C0F01A6645125" + }, + { + "Path": "03_RaffleGroups\\mainwindow.ui", + "Bytes": 10094, + "SHA256": "CFE1DF1AA0BC5BA33F3663D7EDA804F50C9109392E4D746C9233A76ED0086F39" + }, + { + "Path": "03_RaffleGroups\\RaffleGroups.pro", + "Bytes": 251, + "SHA256": "9DB543BDBF066146052AB20D9AE62E360F1D2226E47B2ACC7C751D7EC91BF8C5" + }, + { + "Path": "03_RaffleGroups\\README.md", + "Bytes": 3651, + "SHA256": "1803EB4191BEA1134B245982840A0A996D88BE5404E9FA272613551B50A214EF" + }, + { + "Path": "03_RaffleGroups\\roster.cpp", + "Bytes": 2619, + "SHA256": "D7BDCCB6AE7141A8187BC31A1B0F6A35F01B182AB9F31C67FEE3F50672EE8B4C" + }, + { + "Path": "03_RaffleGroups\\roster.h", + "Bytes": 729, + "SHA256": "3C606C81BE3546009F6A613A0AF77BFDADE6181BED1C8440C9810682DE7ABC66" + }, + { + "Path": "03_RaffleGroups\\sample_roster.txt", + "Bytes": 121, + "SHA256": "B787A4D366A058D41D9255A5982C85D52FA4455F12A4A65A9ADC8EE36C554C1E" + }, + { + "Path": "03_RaffleGroups\\tests\\test_RaffleGroups.cpp", + "Bytes": 5367, + "SHA256": "199B4CD1F49B2165B3524331060E8C40999FCD3EC4F082E5670F08C25049E192" + }, + { + "Path": "03_RaffleGroups\\tests\\test_RaffleGroups.pro", + "Bytes": 327, + "SHA256": "6EEAE8842CD82013C39B340D6433703F8C30A672119F496C45405AC6D80874FB" + }, + { + "Path": "Run_Qt5.14.2\\使用说明.txt", + "Bytes": 412, + "SHA256": "BD431D99BD6BB8B6AB883B311C9A886A41316C50D2DC265151AF0C0A2AEE10D7" + }, + { + "Path": "Run_Qt5.14.2\\ClassroomTimer.exe", + "Bytes": 119497, + "SHA256": "3FA59945C0CB5D224C8EDBFBC5A194A9F9A4D4616830727B85DD221B12239317" + }, + { + "Path": "Run_Qt5.14.2\\libgcc_s_seh-1.dll", + "Bytes": 74240, + "SHA256": "479907904ACF2836A3E103A192393E98C98CFDDC1B4C0B8FF20A442521900C6A" + }, + { + "Path": "Run_Qt5.14.2\\libstdc++-6.dll", + "Bytes": 1425920, + "SHA256": "CDD31659DEDFC2AAC51B2CABB77C061603FD3F91FE98958B9C179CC3F4AC6104" + }, + { + "Path": "Run_Qt5.14.2\\libwinpthread-1.dll", + "Bytes": 52224, + "SHA256": "BD4F622A67E6F33AEC119D987B1AE2B0FC52B8D5A1B2A805AAB654D507F569D3" + }, + { + "Path": "Run_Qt5.14.2\\qt.conf", + "Bytes": 27, + "SHA256": "D23E982F2910242A2BCDF7DABE68B036DE9D2BB8FFAD64FA9F86020C3AD118A4" + }, + { + "Path": "Run_Qt5.14.2\\Qt5Core.dll", + "Bytes": 8343776, + "SHA256": "019AB6AA811087B36D0A91C35A70B8EB7756B7F0F072AFA0449B3805CCAC7EFC" + }, + { + "Path": "Run_Qt5.14.2\\Qt5Gui.dll", + "Bytes": 9844240, + "SHA256": "43DEED28133C0E530ED44FFF3649A87022A80BDB4EF493048518C72AC4656B99" + }, + { + "Path": "Run_Qt5.14.2\\Qt5Widgets.dll", + "Bytes": 8623912, + "SHA256": "90FE759952447724DA52351E7BCEE6F51248B5D9577AB39F22BFD548C8931DE9" + }, + { + "Path": "Run_Qt5.14.2\\RaffleGroups.exe", + "Bytes": 148616, + "SHA256": "73217FC7CDED5755FE2C76AFB7EB2165EA4C1C637D8936A15AABAF30AC7AB277" + }, + { + "Path": "Run_Qt5.14.2\\UnitConverter.exe", + "Bytes": 136248, + "SHA256": "626CE8709EF092C45AC9E41B93AF14DEA0E94BDDD1375CFC19A060EFB790FE72" + }, + { + "Path": "Run_Qt5.14.2\\licenses\\第三方组件说明.txt", + "Bytes": 656, + "SHA256": "B5938BE4B6562FFF6EAC0CC33EA5946E8909896C05977AEA747EA0DD860236B3" + }, + { + "Path": "Run_Qt5.14.2\\licenses\\GCC-GPL-3.txt", + "Bytes": 35147, + "SHA256": "8CEB4B9EE5ADEDDE47B31E975C1D90C73AD27B6B165A1DCD80C7C545EB65B903" + }, + { + "Path": "Run_Qt5.14.2\\licenses\\GCC-Runtime-Exception.txt", + "Bytes": 3324, + "SHA256": "9D6B43CE4D8DE0C878BF16B54D8E7A10D9BD42B75178153E3AF6A815BDC90F74" + }, + { + "Path": "Run_Qt5.14.2\\licenses\\MinGW-runtime.txt", + "Bytes": 10918, + "SHA256": "36A4857B6557A97BAA82762444FFD6A74C7575015595DC26FF02215C299F81F6" + }, + { + "Path": "Run_Qt5.14.2\\licenses\\Qt-GPL-3.txt", + "Bytes": 35821, + "SHA256": "0B383D5A63DA644F628D99C33976EA6487ED89AAA59F0B3257992DEAC1171E6B" + }, + { + "Path": "Run_Qt5.14.2\\licenses\\Qt-LGPL-3.txt", + "Bytes": 7816, + "SHA256": "EA7D049C7705DC13AFC202DD18E1827F3484F8212FD3FA7B82FC4A0C363432C9" + }, + { + "Path": "Run_Qt5.14.2\\licenses\\winpthreads.txt", + "Bytes": 2883, + "SHA256": "63263614CDD29F2F93CBA85E992F041B31F9FC7B4033692F31269489A8A1B177" + }, + { + "Path": "Run_Qt5.14.2\\platforms\\qwindows.dll", + "Bytes": 2849024, + "SHA256": "8F462FD49888E422BB459628AFE97A7A856F51BC8408C91F6175D77AA978B605" + }, + { + "Path": "verification\\验证说明.md", + "Bytes": 2537, + "SHA256": "27B0246774D54E063B53ED6A1C77D88DAB4E9FD0A63D3E17ED8B6ED5DF23A6CA" + }, + { + "Path": "verification\\portable_smoke.txt", + "Bytes": 231, + "SHA256": "626B47068405FF67348C15C0F89E6388F7A543DD5D1AE216E0E363E4104B83B4" + }, + { + "Path": "verification\\qmake683_build.txt", + "Bytes": 18069, + "SHA256": "D38AA692B8B916EDC53B30CDB9002EC763ECC23E91244D6A2CBB55CDBED0ED44" + }, + { + "Path": "verification\\qt5142_ClassroomTimer.txt", + "Bytes": 679, + "SHA256": "0C18D45B89173EB612A868F79C474490D9164CA8C781AB85916EE9BDE4DDDB40" + }, + { + "Path": "verification\\qt5142_RaffleGroups.txt", + "Bytes": 677, + "SHA256": "FE6DD18903780A156A197AB7048DA5225CD0DB41E54F2045144B51F750185085" + }, + { + "Path": "verification\\qt5142_UnitConverter.txt", + "Bytes": 1191, + "SHA256": "763725EA7A34E0A0014DEBCD0A20330A3F882823E6FC4F8F1F9EC8C01DF50C84" + }, + { + "Path": "verification\\qt683_ClassroomTimer.txt", + "Bytes": 690, + "SHA256": "CE7C41FA312973BE132B1144CE966C33F1B5ED8A5D22DB09D62A4311A948597E" + }, + { + "Path": "verification\\qt683_RaffleGroups.txt", + "Bytes": 688, + "SHA256": "2CD33A7E124A717F4A4AFE0DA533C680305CB697C1050CD3CDEAAF193873268A" + }, + { + "Path": "verification\\qt683_UnitConverter.txt", + "Bytes": 1202, + "SHA256": "35228DC497EC0F17ABFFAC18DDC28CE23D95C5DEE5BE055DC9C57336713449EC" + }, + { + "Path": "verification\\screenshots_qt5142\\01_converter.png", + "Bytes": 60422, + "SHA256": "AECC6DE47E6EC08A037D168E242D49511AD5874F43CFE846518C98AA606E7496" + }, + { + "Path": "verification\\screenshots_qt5142\\02_timer.png", + "Bytes": 41393, + "SHA256": "6CA8C94701FF5D8DDC985E606E6F356BBC13DBE84664E0F2EA431182D6C92D70" + }, + { + "Path": "verification\\screenshots_qt5142\\03_groups.png", + "Bytes": 92544, + "SHA256": "64DD910770BAF4C09B6C525A705F369B5350766D86E481098BA8615762EC0D2C" + }, + { + "Path": "verification\\screenshots_qt5142\\03_raffle.png", + "Bytes": 70879, + "SHA256": "53F205D53857004B97547DC7DAE7C897422DC808660B6DFB443FA962AF6E7BA8" + } +] diff --git a/Projects/verification/portable_smoke.txt b/Projects/verification/portable_smoke.txt new file mode 100644 index 0000000..622b50d --- /dev/null +++ b/Projects/verification/portable_smoke.txt @@ -0,0 +1,3 @@ +UnitConverter.exe : passed (local runtime, windows platform, normal exit 0) +ClassroomTimer.exe : passed (local runtime, windows platform, normal exit 0) +RaffleGroups.exe : passed (local runtime, windows platform, normal exit 0) diff --git a/Projects/verification/qmake683_build.txt b/Projects/verification/qmake683_build.txt new file mode 100644 index 0000000..30b1a90 --- /dev/null +++ b/Projects/verification/qmake683_build.txt @@ -0,0 +1,33 @@ +cd 01_UnitConverter\ && ( if not exist Makefile.UnitConverter D:\Qt\6.8.3\mingw_64\bin\qmake.exe -o Makefile.UnitConverter C:\Users\xiaolinquan\.codex\visualizations\2026\10\01\01a0f7bf-59fd-7ee0-92ab-1e0ae9b29cff\qt_widgets_projects\01_UnitConverter\UnitConverter.pro "CONFIG+=release" "CONFIG-=debug" "CONFIG-=debug_and_release" ) && D:/Qt/Tools/mingw1310_64/bin/mingw32-make -f Makefile.UnitConverter +cd 02_ClassroomTimer\ && ( if not exist Makefile.ClassroomTimer D:\Qt\6.8.3\mingw_64\bin\qmake.exe -o Makefile.ClassroomTimer C:\Users\xiaolinquan\.codex\visualizations\2026\10\01\01a0f7bf-59fd-7ee0-92ab-1e0ae9b29cff\qt_widgets_projects\02_ClassroomTimer\ClassroomTimer.pro "CONFIG+=release" "CONFIG-=debug" "CONFIG-=debug_and_release" ) && D:/Qt/Tools/mingw1310_64/bin/mingw32-make -f Makefile.ClassroomTimer +cd 03_RaffleGroups\ && ( if not exist Makefile.RaffleGroups D:\Qt\6.8.3\mingw_64\bin\qmake.exe -o Makefile.RaffleGroups C:\Users\xiaolinquan\.codex\visualizations\2026\10\01\01a0f7bf-59fd-7ee0-92ab-1e0ae9b29cff\qt_widgets_projects\03_RaffleGroups\RaffleGroups.pro "CONFIG+=release" "CONFIG-=debug" "CONFIG-=debug_and_release" ) && D:/Qt/Tools/mingw1310_64/bin/mingw32-make -f Makefile.RaffleGroups +mingw32-make[1]: Entering directory 'C:/Users/xiaolinquan/.codex/visualizations/2026/10/01/01a0f7bf-59fd-7ee0-92ab-1e0ae9b29cff/qt_qmake683/01_UnitConverter' +D:\Qt\6.8.3\mingw_64\bin\uic.exe ..\..\qt_widgets_projects\01_UnitConverter\mainwindow.ui -o ui_mainwindow.h +mingw32-make[1]: Entering directory 'C:/Users/xiaolinquan/.codex/visualizations/2026/10/01/01a0f7bf-59fd-7ee0-92ab-1e0ae9b29cff/qt_qmake683/02_ClassroomTimer' +D:\Qt\6.8.3\mingw_64\bin\uic.exe ..\..\qt_widgets_projects\02_ClassroomTimer\mainwindow.ui -o ui_mainwindow.h +mingw32-make[1]: Entering directory 'C:/Users/xiaolinquan/.codex/visualizations/2026/10/01/01a0f7bf-59fd-7ee0-92ab-1e0ae9b29cff/qt_qmake683/03_RaffleGroups' +D:\Qt\6.8.3\mingw_64\bin\uic.exe ..\..\qt_widgets_projects\03_RaffleGroups\mainwindow.ui -o ui_mainwindow.h +g++ -c -fno-keep-inline-dllexport -O2 -std=gnu++1z -Wall -Wextra -Wextra -fexceptions -mthreads -DUNICODE -D_UNICODE -DWIN32 -DMINGW_HAS_SECURE_API=1 -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DQT_NEEDS_QMAIN -I../../qt_widgets_projects/01_UnitConverter -IC:/Users/xiaolinquan/.codex/visualizations/2026/10/01/01a0f7bf-59fd-7ee0-92ab-1e0ae9b29cff/qt_qmake683/01_UnitConverter -ID:/Qt/6.8.3/mingw_64/include -ID:/Qt/6.8.3/mingw_64/include/QtWidgets -ID:/Qt/6.8.3/mingw_64/include/QtGui -ID:/Qt/6.8.3/mingw_64/include/QtCore -IC:/Users/xiaolinquan/.codex/visualizations/2026/10/01/01a0f7bf-59fd-7ee0-92ab-1e0ae9b29cff/qt_qmake683/01_UnitConverter -IC:/Users/xiaolinquan/.codex/visualizations/2026/10/01/01a0f7bf-59fd-7ee0-92ab-1e0ae9b29cff/qt_qmake683/01_UnitConverter -I/include -ID:/Qt/6.8.3/mingw_64/mkspecs/win32-g++ -o main.o ..\..\qt_widgets_projects\01_UnitConverter\main.cpp +g++ -c -fno-keep-inline-dllexport -O2 -std=gnu++1z -Wall -Wextra -Wextra -fexceptions -mthreads -DUNICODE -D_UNICODE -DWIN32 -DMINGW_HAS_SECURE_API=1 -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DQT_NEEDS_QMAIN -I../../qt_widgets_projects/03_RaffleGroups -IC:/Users/xiaolinquan/.codex/visualizations/2026/10/01/01a0f7bf-59fd-7ee0-92ab-1e0ae9b29cff/qt_qmake683/03_RaffleGroups -ID:/Qt/6.8.3/mingw_64/include -ID:/Qt/6.8.3/mingw_64/include/QtWidgets -ID:/Qt/6.8.3/mingw_64/include/QtGui -ID:/Qt/6.8.3/mingw_64/include/QtCore -IC:/Users/xiaolinquan/.codex/visualizations/2026/10/01/01a0f7bf-59fd-7ee0-92ab-1e0ae9b29cff/qt_qmake683/03_RaffleGroups -IC:/Users/xiaolinquan/.codex/visualizations/2026/10/01/01a0f7bf-59fd-7ee0-92ab-1e0ae9b29cff/qt_qmake683/03_RaffleGroups -I/include -ID:/Qt/6.8.3/mingw_64/mkspecs/win32-g++ -o main.o ..\..\qt_widgets_projects\03_RaffleGroups\main.cpp +g++ -c -fno-keep-inline-dllexport -O2 -std=gnu++1z -Wall -Wextra -Wextra -fexceptions -mthreads -DUNICODE -D_UNICODE -DWIN32 -DMINGW_HAS_SECURE_API=1 -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DQT_NEEDS_QMAIN -I../../qt_widgets_projects/02_ClassroomTimer -IC:/Users/xiaolinquan/.codex/visualizations/2026/10/01/01a0f7bf-59fd-7ee0-92ab-1e0ae9b29cff/qt_qmake683/02_ClassroomTimer -ID:/Qt/6.8.3/mingw_64/include -ID:/Qt/6.8.3/mingw_64/include/QtWidgets -ID:/Qt/6.8.3/mingw_64/include/QtGui -ID:/Qt/6.8.3/mingw_64/include/QtCore -IC:/Users/xiaolinquan/.codex/visualizations/2026/10/01/01a0f7bf-59fd-7ee0-92ab-1e0ae9b29cff/qt_qmake683/02_ClassroomTimer -IC:/Users/xiaolinquan/.codex/visualizations/2026/10/01/01a0f7bf-59fd-7ee0-92ab-1e0ae9b29cff/qt_qmake683/02_ClassroomTimer -I/include -ID:/Qt/6.8.3/mingw_64/mkspecs/win32-g++ -o main.o ..\..\qt_widgets_projects\02_ClassroomTimer\main.cpp +g++ -c -fno-keep-inline-dllexport -O2 -std=gnu++1z -Wall -Wextra -Wextra -fexceptions -mthreads -DUNICODE -D_UNICODE -DWIN32 -DMINGW_HAS_SECURE_API=1 -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DQT_NEEDS_QMAIN -I../../qt_widgets_projects/01_UnitConverter -IC:/Users/xiaolinquan/.codex/visualizations/2026/10/01/01a0f7bf-59fd-7ee0-92ab-1e0ae9b29cff/qt_qmake683/01_UnitConverter -ID:/Qt/6.8.3/mingw_64/include -ID:/Qt/6.8.3/mingw_64/include/QtWidgets -ID:/Qt/6.8.3/mingw_64/include/QtGui -ID:/Qt/6.8.3/mingw_64/include/QtCore -IC:/Users/xiaolinquan/.codex/visualizations/2026/10/01/01a0f7bf-59fd-7ee0-92ab-1e0ae9b29cff/qt_qmake683/01_UnitConverter -IC:/Users/xiaolinquan/.codex/visualizations/2026/10/01/01a0f7bf-59fd-7ee0-92ab-1e0ae9b29cff/qt_qmake683/01_UnitConverter -I/include -ID:/Qt/6.8.3/mingw_64/mkspecs/win32-g++ -o mainwindow.o ..\..\qt_widgets_projects\01_UnitConverter\mainwindow.cpp +g++ -c -fno-keep-inline-dllexport -O2 -std=gnu++1z -Wall -Wextra -Wextra -fexceptions -mthreads -DUNICODE -D_UNICODE -DWIN32 -DMINGW_HAS_SECURE_API=1 -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DQT_NEEDS_QMAIN -I../../qt_widgets_projects/02_ClassroomTimer -IC:/Users/xiaolinquan/.codex/visualizations/2026/10/01/01a0f7bf-59fd-7ee0-92ab-1e0ae9b29cff/qt_qmake683/02_ClassroomTimer -ID:/Qt/6.8.3/mingw_64/include -ID:/Qt/6.8.3/mingw_64/include/QtWidgets -ID:/Qt/6.8.3/mingw_64/include/QtGui -ID:/Qt/6.8.3/mingw_64/include/QtCore -IC:/Users/xiaolinquan/.codex/visualizations/2026/10/01/01a0f7bf-59fd-7ee0-92ab-1e0ae9b29cff/qt_qmake683/02_ClassroomTimer -IC:/Users/xiaolinquan/.codex/visualizations/2026/10/01/01a0f7bf-59fd-7ee0-92ab-1e0ae9b29cff/qt_qmake683/02_ClassroomTimer -I/include -ID:/Qt/6.8.3/mingw_64/mkspecs/win32-g++ -o mainwindow.o ..\..\qt_widgets_projects\02_ClassroomTimer\mainwindow.cpp +g++ -c -fno-keep-inline-dllexport -O2 -std=gnu++1z -Wall -Wextra -Wextra -fexceptions -mthreads -DUNICODE -D_UNICODE -DWIN32 -DMINGW_HAS_SECURE_API=1 -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DQT_NEEDS_QMAIN -I../../qt_widgets_projects/03_RaffleGroups -IC:/Users/xiaolinquan/.codex/visualizations/2026/10/01/01a0f7bf-59fd-7ee0-92ab-1e0ae9b29cff/qt_qmake683/03_RaffleGroups -ID:/Qt/6.8.3/mingw_64/include -ID:/Qt/6.8.3/mingw_64/include/QtWidgets -ID:/Qt/6.8.3/mingw_64/include/QtGui -ID:/Qt/6.8.3/mingw_64/include/QtCore -IC:/Users/xiaolinquan/.codex/visualizations/2026/10/01/01a0f7bf-59fd-7ee0-92ab-1e0ae9b29cff/qt_qmake683/03_RaffleGroups -IC:/Users/xiaolinquan/.codex/visualizations/2026/10/01/01a0f7bf-59fd-7ee0-92ab-1e0ae9b29cff/qt_qmake683/03_RaffleGroups -I/include -ID:/Qt/6.8.3/mingw_64/mkspecs/win32-g++ -o mainwindow.o ..\..\qt_widgets_projects\03_RaffleGroups\mainwindow.cpp +g++ -c -fno-keep-inline-dllexport -O2 -std=gnu++1z -Wall -Wextra -Wextra -fexceptions -mthreads -DUNICODE -D_UNICODE -DWIN32 -DMINGW_HAS_SECURE_API=1 -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DQT_NEEDS_QMAIN -I../../qt_widgets_projects/01_UnitConverter -IC:/Users/xiaolinquan/.codex/visualizations/2026/10/01/01a0f7bf-59fd-7ee0-92ab-1e0ae9b29cff/qt_qmake683/01_UnitConverter -ID:/Qt/6.8.3/mingw_64/include -ID:/Qt/6.8.3/mingw_64/include/QtWidgets -ID:/Qt/6.8.3/mingw_64/include/QtGui -ID:/Qt/6.8.3/mingw_64/include/QtCore -IC:/Users/xiaolinquan/.codex/visualizations/2026/10/01/01a0f7bf-59fd-7ee0-92ab-1e0ae9b29cff/qt_qmake683/01_UnitConverter -IC:/Users/xiaolinquan/.codex/visualizations/2026/10/01/01a0f7bf-59fd-7ee0-92ab-1e0ae9b29cff/qt_qmake683/01_UnitConverter -I/include -ID:/Qt/6.8.3/mingw_64/mkspecs/win32-g++ -o conversion.o ..\..\qt_widgets_projects\01_UnitConverter\conversion.cpp +g++ -c -fno-keep-inline-dllexport -O2 -std=gnu++1z -Wall -Wextra -Wextra -fexceptions -mthreads -DUNICODE -D_UNICODE -DWIN32 -DMINGW_HAS_SECURE_API=1 -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DQT_NEEDS_QMAIN -I../../qt_widgets_projects/03_RaffleGroups -IC:/Users/xiaolinquan/.codex/visualizations/2026/10/01/01a0f7bf-59fd-7ee0-92ab-1e0ae9b29cff/qt_qmake683/03_RaffleGroups -ID:/Qt/6.8.3/mingw_64/include -ID:/Qt/6.8.3/mingw_64/include/QtWidgets -ID:/Qt/6.8.3/mingw_64/include/QtGui -ID:/Qt/6.8.3/mingw_64/include/QtCore -IC:/Users/xiaolinquan/.codex/visualizations/2026/10/01/01a0f7bf-59fd-7ee0-92ab-1e0ae9b29cff/qt_qmake683/03_RaffleGroups -IC:/Users/xiaolinquan/.codex/visualizations/2026/10/01/01a0f7bf-59fd-7ee0-92ab-1e0ae9b29cff/qt_qmake683/03_RaffleGroups -I/include -ID:/Qt/6.8.3/mingw_64/mkspecs/win32-g++ -o roster.o ..\..\qt_widgets_projects\03_RaffleGroups\roster.cpp +g++ -c -fno-keep-inline-dllexport -O2 -std=gnu++1z -Wall -Wextra -Wextra -fexceptions -mthreads -DUNICODE -D_UNICODE -DWIN32 -DMINGW_HAS_SECURE_API=1 -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DQT_NEEDS_QMAIN -I../../qt_widgets_projects/02_ClassroomTimer -IC:/Users/xiaolinquan/.codex/visualizations/2026/10/01/01a0f7bf-59fd-7ee0-92ab-1e0ae9b29cff/qt_qmake683/02_ClassroomTimer -ID:/Qt/6.8.3/mingw_64/include -ID:/Qt/6.8.3/mingw_64/include/QtWidgets -ID:/Qt/6.8.3/mingw_64/include/QtGui -ID:/Qt/6.8.3/mingw_64/include/QtCore -IC:/Users/xiaolinquan/.codex/visualizations/2026/10/01/01a0f7bf-59fd-7ee0-92ab-1e0ae9b29cff/qt_qmake683/02_ClassroomTimer -IC:/Users/xiaolinquan/.codex/visualizations/2026/10/01/01a0f7bf-59fd-7ee0-92ab-1e0ae9b29cff/qt_qmake683/02_ClassroomTimer -I/include -ID:/Qt/6.8.3/mingw_64/mkspecs/win32-g++ -o countdown.o ..\..\qt_widgets_projects\02_ClassroomTimer\countdown.cpp +g++ -fno-keep-inline-dllexport -O2 -std=gnu++1z -Wall -Wextra -Wextra -dM -E -o moc_predefs.h D:\Qt\6.8.3\mingw_64\mkspecs\features\data\dummy.cpp +D:\Qt\6.8.3\mingw_64\bin\moc.exe -DUNICODE -D_UNICODE -DWIN32 -DMINGW_HAS_SECURE_API=1 -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DQT_NEEDS_QMAIN --include C:/Users/xiaolinquan/.codex/visualizations/2026/10/01/01a0f7bf-59fd-7ee0-92ab-1e0ae9b29cff/qt_qmake683/01_UnitConverter/moc_predefs.h -ID:/Qt/6.8.3/mingw_64/mkspecs/win32-g++ -IC:/Users/xiaolinquan/.codex/visualizations/2026/10/01/01a0f7bf-59fd-7ee0-92ab-1e0ae9b29cff/qt_widgets_projects/01_UnitConverter -ID:/Qt/6.8.3/mingw_64/include -ID:/Qt/6.8.3/mingw_64/include/QtWidgets -ID:/Qt/6.8.3/mingw_64/include/QtGui -ID:/Qt/6.8.3/mingw_64/include/QtCore -I. -ID:/Qt/Tools/mingw1310_64/lib/gcc/x86_64-w64-mingw32/13.1.0/include/c++ -ID:/Qt/Tools/mingw1310_64/lib/gcc/x86_64-w64-mingw32/13.1.0/include/c++/x86_64-w64-mingw32 -ID:/Qt/Tools/mingw1310_64/lib/gcc/x86_64-w64-mingw32/13.1.0/include/c++/backward -ID:/Qt/Tools/mingw1310_64/lib/gcc/x86_64-w64-mingw32/13.1.0/include -ID:/Qt/Tools/mingw1310_64/lib/gcc/x86_64-w64-mingw32/13.1.0/include-fixed -ID:/Qt/Tools/mingw1310_64/x86_64-w64-mingw32/include ..\..\qt_widgets_projects\01_UnitConverter\mainwindow.h -o moc_mainwindow.cpp +g++ -fno-keep-inline-dllexport -O2 -std=gnu++1z -Wall -Wextra -Wextra -dM -E -o moc_predefs.h D:\Qt\6.8.3\mingw_64\mkspecs\features\data\dummy.cpp +g++ -fno-keep-inline-dllexport -O2 -std=gnu++1z -Wall -Wextra -Wextra -dM -E -o moc_predefs.h D:\Qt\6.8.3\mingw_64\mkspecs\features\data\dummy.cpp +D:\Qt\6.8.3\mingw_64\bin\moc.exe -DUNICODE -D_UNICODE -DWIN32 -DMINGW_HAS_SECURE_API=1 -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DQT_NEEDS_QMAIN --include C:/Users/xiaolinquan/.codex/visualizations/2026/10/01/01a0f7bf-59fd-7ee0-92ab-1e0ae9b29cff/qt_qmake683/02_ClassroomTimer/moc_predefs.h -ID:/Qt/6.8.3/mingw_64/mkspecs/win32-g++ -IC:/Users/xiaolinquan/.codex/visualizations/2026/10/01/01a0f7bf-59fd-7ee0-92ab-1e0ae9b29cff/qt_widgets_projects/02_ClassroomTimer -ID:/Qt/6.8.3/mingw_64/include -ID:/Qt/6.8.3/mingw_64/include/QtWidgets -ID:/Qt/6.8.3/mingw_64/include/QtGui -ID:/Qt/6.8.3/mingw_64/include/QtCore -I. -ID:/Qt/Tools/mingw1310_64/lib/gcc/x86_64-w64-mingw32/13.1.0/include/c++ -ID:/Qt/Tools/mingw1310_64/lib/gcc/x86_64-w64-mingw32/13.1.0/include/c++/x86_64-w64-mingw32 -ID:/Qt/Tools/mingw1310_64/lib/gcc/x86_64-w64-mingw32/13.1.0/include/c++/backward -ID:/Qt/Tools/mingw1310_64/lib/gcc/x86_64-w64-mingw32/13.1.0/include -ID:/Qt/Tools/mingw1310_64/lib/gcc/x86_64-w64-mingw32/13.1.0/include-fixed -ID:/Qt/Tools/mingw1310_64/x86_64-w64-mingw32/include ..\..\qt_widgets_projects\02_ClassroomTimer\mainwindow.h -o moc_mainwindow.cpp +D:\Qt\6.8.3\mingw_64\bin\moc.exe -DUNICODE -D_UNICODE -DWIN32 -DMINGW_HAS_SECURE_API=1 -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DQT_NEEDS_QMAIN --include C:/Users/xiaolinquan/.codex/visualizations/2026/10/01/01a0f7bf-59fd-7ee0-92ab-1e0ae9b29cff/qt_qmake683/03_RaffleGroups/moc_predefs.h -ID:/Qt/6.8.3/mingw_64/mkspecs/win32-g++ -IC:/Users/xiaolinquan/.codex/visualizations/2026/10/01/01a0f7bf-59fd-7ee0-92ab-1e0ae9b29cff/qt_widgets_projects/03_RaffleGroups -ID:/Qt/6.8.3/mingw_64/include -ID:/Qt/6.8.3/mingw_64/include/QtWidgets -ID:/Qt/6.8.3/mingw_64/include/QtGui -ID:/Qt/6.8.3/mingw_64/include/QtCore -I. -ID:/Qt/Tools/mingw1310_64/lib/gcc/x86_64-w64-mingw32/13.1.0/include/c++ -ID:/Qt/Tools/mingw1310_64/lib/gcc/x86_64-w64-mingw32/13.1.0/include/c++/x86_64-w64-mingw32 -ID:/Qt/Tools/mingw1310_64/lib/gcc/x86_64-w64-mingw32/13.1.0/include/c++/backward -ID:/Qt/Tools/mingw1310_64/lib/gcc/x86_64-w64-mingw32/13.1.0/include -ID:/Qt/Tools/mingw1310_64/lib/gcc/x86_64-w64-mingw32/13.1.0/include-fixed -ID:/Qt/Tools/mingw1310_64/x86_64-w64-mingw32/include ..\..\qt_widgets_projects\03_RaffleGroups\mainwindow.h -o moc_mainwindow.cpp +g++ -c -fno-keep-inline-dllexport -O2 -std=gnu++1z -Wall -Wextra -Wextra -fexceptions -mthreads -DUNICODE -D_UNICODE -DWIN32 -DMINGW_HAS_SECURE_API=1 -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DQT_NEEDS_QMAIN -I../../qt_widgets_projects/01_UnitConverter -IC:/Users/xiaolinquan/.codex/visualizations/2026/10/01/01a0f7bf-59fd-7ee0-92ab-1e0ae9b29cff/qt_qmake683/01_UnitConverter -ID:/Qt/6.8.3/mingw_64/include -ID:/Qt/6.8.3/mingw_64/include/QtWidgets -ID:/Qt/6.8.3/mingw_64/include/QtGui -ID:/Qt/6.8.3/mingw_64/include/QtCore -IC:/Users/xiaolinquan/.codex/visualizations/2026/10/01/01a0f7bf-59fd-7ee0-92ab-1e0ae9b29cff/qt_qmake683/01_UnitConverter -IC:/Users/xiaolinquan/.codex/visualizations/2026/10/01/01a0f7bf-59fd-7ee0-92ab-1e0ae9b29cff/qt_qmake683/01_UnitConverter -I/include -ID:/Qt/6.8.3/mingw_64/mkspecs/win32-g++ -o moc_mainwindow.o moc_mainwindow.cpp +g++ -c -fno-keep-inline-dllexport -O2 -std=gnu++1z -Wall -Wextra -Wextra -fexceptions -mthreads -DUNICODE -D_UNICODE -DWIN32 -DMINGW_HAS_SECURE_API=1 -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DQT_NEEDS_QMAIN -I../../qt_widgets_projects/02_ClassroomTimer -IC:/Users/xiaolinquan/.codex/visualizations/2026/10/01/01a0f7bf-59fd-7ee0-92ab-1e0ae9b29cff/qt_qmake683/02_ClassroomTimer -ID:/Qt/6.8.3/mingw_64/include -ID:/Qt/6.8.3/mingw_64/include/QtWidgets -ID:/Qt/6.8.3/mingw_64/include/QtGui -ID:/Qt/6.8.3/mingw_64/include/QtCore -IC:/Users/xiaolinquan/.codex/visualizations/2026/10/01/01a0f7bf-59fd-7ee0-92ab-1e0ae9b29cff/qt_qmake683/02_ClassroomTimer -IC:/Users/xiaolinquan/.codex/visualizations/2026/10/01/01a0f7bf-59fd-7ee0-92ab-1e0ae9b29cff/qt_qmake683/02_ClassroomTimer -I/include -ID:/Qt/6.8.3/mingw_64/mkspecs/win32-g++ -o moc_mainwindow.o moc_mainwindow.cpp +g++ -c -fno-keep-inline-dllexport -O2 -std=gnu++1z -Wall -Wextra -Wextra -fexceptions -mthreads -DUNICODE -D_UNICODE -DWIN32 -DMINGW_HAS_SECURE_API=1 -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DQT_NEEDS_QMAIN -I../../qt_widgets_projects/03_RaffleGroups -IC:/Users/xiaolinquan/.codex/visualizations/2026/10/01/01a0f7bf-59fd-7ee0-92ab-1e0ae9b29cff/qt_qmake683/03_RaffleGroups -ID:/Qt/6.8.3/mingw_64/include -ID:/Qt/6.8.3/mingw_64/include/QtWidgets -ID:/Qt/6.8.3/mingw_64/include/QtGui -ID:/Qt/6.8.3/mingw_64/include/QtCore -IC:/Users/xiaolinquan/.codex/visualizations/2026/10/01/01a0f7bf-59fd-7ee0-92ab-1e0ae9b29cff/qt_qmake683/03_RaffleGroups -IC:/Users/xiaolinquan/.codex/visualizations/2026/10/01/01a0f7bf-59fd-7ee0-92ab-1e0ae9b29cff/qt_qmake683/03_RaffleGroups -I/include -ID:/Qt/6.8.3/mingw_64/mkspecs/win32-g++ -o moc_mainwindow.o moc_mainwindow.cpp +g++ -Wl,-s -Wl,-subsystem,windows -mthreads -o UnitConverter.exe main.o mainwindow.o conversion.o moc_mainwindow.o D:\Qt\6.8.3\mingw_64\lib\libQt6Widgets.a D:\Qt\6.8.3\mingw_64\lib\libQt6Gui.a D:\Qt\6.8.3\mingw_64\lib\libQt6Core.a -lmingw32 D:\Qt\6.8.3\mingw_64\lib\libQt6EntryPoint.a -lshell32 +g++ -Wl,-s -Wl,-subsystem,windows -mthreads -o ClassroomTimer.exe main.o mainwindow.o countdown.o moc_mainwindow.o D:\Qt\6.8.3\mingw_64\lib\libQt6Widgets.a D:\Qt\6.8.3\mingw_64\lib\libQt6Gui.a D:\Qt\6.8.3\mingw_64\lib\libQt6Core.a -lmingw32 D:\Qt\6.8.3\mingw_64\lib\libQt6EntryPoint.a -lshell32 +mingw32-make[1]: Leaving directory 'C:/Users/xiaolinquan/.codex/visualizations/2026/10/01/01a0f7bf-59fd-7ee0-92ab-1e0ae9b29cff/qt_qmake683/01_UnitConverter' +g++ -Wl,-s -Wl,-subsystem,windows -mthreads -o RaffleGroups.exe main.o mainwindow.o roster.o moc_mainwindow.o D:\Qt\6.8.3\mingw_64\lib\libQt6Widgets.a D:\Qt\6.8.3\mingw_64\lib\libQt6Gui.a D:\Qt\6.8.3\mingw_64\lib\libQt6Core.a -lmingw32 D:\Qt\6.8.3\mingw_64\lib\libQt6EntryPoint.a -lshell32 +mingw32-make[1]: Leaving directory 'C:/Users/xiaolinquan/.codex/visualizations/2026/10/01/01a0f7bf-59fd-7ee0-92ab-1e0ae9b29cff/qt_qmake683/02_ClassroomTimer' +mingw32-make[1]: Leaving directory 'C:/Users/xiaolinquan/.codex/visualizations/2026/10/01/01a0f7bf-59fd-7ee0-92ab-1e0ae9b29cff/qt_qmake683/03_RaffleGroups' diff --git a/Projects/verification/qt5142_ClassroomTimer.txt b/Projects/verification/qt5142_ClassroomTimer.txt new file mode 100644 index 0000000..78541dd --- /dev/null +++ b/Projects/verification/qt5142_ClassroomTimer.txt @@ -0,0 +1,12 @@ +********* Start testing of TimerTest ********* +Config: Using QtTest library 5.14.2, Qt 5.14.2 (x86_64-little_endian-llp64 shared (dynamic) release build; by GCC 7.3.0) +PASS : TimerTest::initTestCase() +PASS : TimerTest::pauseResumeAndDrift() +PASS : TimerTest::delayedRefreshAndReset() +PASS : TimerTest::zeroAndDeadlinePause() +QDEBUG : TimerTest::uiWorkflow() FT_New_Face failed with index 0 : 2 +QWARN : TimerTest::uiWorkflow() This plugin does not support propagateSizeHints() +PASS : TimerTest::uiWorkflow() +PASS : TimerTest::cleanupTestCase() +Totals: 6 passed, 0 failed, 0 skipped, 0 blacklisted, 1460ms +********* Finished testing of TimerTest ********* diff --git a/Projects/verification/qt5142_RaffleGroups.txt b/Projects/verification/qt5142_RaffleGroups.txt new file mode 100644 index 0000000..c0380be --- /dev/null +++ b/Projects/verification/qt5142_RaffleGroups.txt @@ -0,0 +1,12 @@ +********* Start testing of RaffleTest ********* +Config: Using QtTest library 5.14.2, Qt 5.14.2 (x86_64-little_endian-llp64 shared (dynamic) release build; by GCC 7.3.0) +PASS : RaffleTest::initTestCase() +PASS : RaffleTest::parsing() +PASS : RaffleTest::drawingWithoutReplacement() +PASS : RaffleTest::groupingInvariants() +QDEBUG : RaffleTest::uiWorkflow() FT_New_Face failed with index 0 : 2 +QWARN : RaffleTest::uiWorkflow() This plugin does not support propagateSizeHints() +PASS : RaffleTest::uiWorkflow() +PASS : RaffleTest::cleanupTestCase() +Totals: 6 passed, 0 failed, 0 skipped, 0 blacklisted, 249ms +********* Finished testing of RaffleTest ********* diff --git a/Projects/verification/qt5142_UnitConverter.txt b/Projects/verification/qt5142_UnitConverter.txt new file mode 100644 index 0000000..9d2cb51 --- /dev/null +++ b/Projects/verification/qt5142_UnitConverter.txt @@ -0,0 +1,22 @@ +********* Start testing of ConverterTest ********* +Config: Using QtTest library 5.14.2, Qt 5.14.2 (x86_64-little_endian-llp64 shared (dynamic) release build; by GCC 7.3.0) +PASS : ConverterTest::initTestCase() +PASS : ConverterTest::knownValues(freezing) +PASS : ConverterTest::knownValues(boiling) +PASS : ConverterTest::knownValues(minus40) +PASS : ConverterTest::knownValues(kelvin) +PASS : ConverterTest::knownValues(absolute-zero-C) +PASS : ConverterTest::knownValues(absolute-zero-F) +PASS : ConverterTest::knownValues(meter-cm) +PASS : ConverterTest::knownValues(inch-cm) +PASS : ConverterTest::knownValues(foot-meter) +PASS : ConverterTest::knownValues(km-mm) +PASS : ConverterTest::knownValues(scientific) +PASS : ConverterTest::knownValues(same-unit) +PASS : ConverterTest::rejectsInvalid() +QDEBUG : ConverterTest::uiWorkflow() FT_New_Face failed with index 0 : 2 +QWARN : ConverterTest::uiWorkflow() This plugin does not support propagateSizeHints() +PASS : ConverterTest::uiWorkflow() +PASS : ConverterTest::cleanupTestCase() +Totals: 16 passed, 0 failed, 0 skipped, 0 blacklisted, 183ms +********* Finished testing of ConverterTest ********* diff --git a/Projects/verification/qt683_ClassroomTimer.txt b/Projects/verification/qt683_ClassroomTimer.txt new file mode 100644 index 0000000..15d9acf --- /dev/null +++ b/Projects/verification/qt683_ClassroomTimer.txt @@ -0,0 +1,12 @@ +********* Start testing of TimerTest ********* +Config: Using QtTest library 6.8.3, Qt 6.8.3 (x86_64-little_endian-llp64 shared (dynamic) release build; by GCC 13.1.0), windows 11 +PASS : TimerTest::initTestCase() +PASS : TimerTest::pauseResumeAndDrift() +PASS : TimerTest::delayedRefreshAndReset() +PASS : TimerTest::zeroAndDeadlinePause() +QDEBUG : TimerTest::uiWorkflow() FT_New_Face failed with index 0 : 2 +QWARN : TimerTest::uiWorkflow() This plugin does not support propagateSizeHints() +PASS : TimerTest::uiWorkflow() +PASS : TimerTest::cleanupTestCase() +Totals: 6 passed, 0 failed, 0 skipped, 0 blacklisted, 1503ms +********* Finished testing of TimerTest ********* diff --git a/Projects/verification/qt683_RaffleGroups.txt b/Projects/verification/qt683_RaffleGroups.txt new file mode 100644 index 0000000..6eacdbd --- /dev/null +++ b/Projects/verification/qt683_RaffleGroups.txt @@ -0,0 +1,12 @@ +********* Start testing of RaffleTest ********* +Config: Using QtTest library 6.8.3, Qt 6.8.3 (x86_64-little_endian-llp64 shared (dynamic) release build; by GCC 13.1.0), windows 11 +PASS : RaffleTest::initTestCase() +PASS : RaffleTest::parsing() +PASS : RaffleTest::drawingWithoutReplacement() +PASS : RaffleTest::groupingInvariants() +QDEBUG : RaffleTest::uiWorkflow() FT_New_Face failed with index 0 : 2 +QWARN : RaffleTest::uiWorkflow() This plugin does not support propagateSizeHints() +PASS : RaffleTest::uiWorkflow() +PASS : RaffleTest::cleanupTestCase() +Totals: 6 passed, 0 failed, 0 skipped, 0 blacklisted, 336ms +********* Finished testing of RaffleTest ********* diff --git a/Projects/verification/qt683_UnitConverter.txt b/Projects/verification/qt683_UnitConverter.txt new file mode 100644 index 0000000..9f14ff5 --- /dev/null +++ b/Projects/verification/qt683_UnitConverter.txt @@ -0,0 +1,22 @@ +********* Start testing of ConverterTest ********* +Config: Using QtTest library 6.8.3, Qt 6.8.3 (x86_64-little_endian-llp64 shared (dynamic) release build; by GCC 13.1.0), windows 11 +PASS : ConverterTest::initTestCase() +PASS : ConverterTest::knownValues(freezing) +PASS : ConverterTest::knownValues(boiling) +PASS : ConverterTest::knownValues(minus40) +PASS : ConverterTest::knownValues(kelvin) +PASS : ConverterTest::knownValues(absolute-zero-C) +PASS : ConverterTest::knownValues(absolute-zero-F) +PASS : ConverterTest::knownValues(meter-cm) +PASS : ConverterTest::knownValues(inch-cm) +PASS : ConverterTest::knownValues(foot-meter) +PASS : ConverterTest::knownValues(km-mm) +PASS : ConverterTest::knownValues(scientific) +PASS : ConverterTest::knownValues(same-unit) +PASS : ConverterTest::rejectsInvalid() +QDEBUG : ConverterTest::uiWorkflow() FT_New_Face failed with index 0 : 2 +QWARN : ConverterTest::uiWorkflow() This plugin does not support propagateSizeHints() +PASS : ConverterTest::uiWorkflow() +PASS : ConverterTest::cleanupTestCase() +Totals: 16 passed, 0 failed, 0 skipped, 0 blacklisted, 280ms +********* Finished testing of ConverterTest ********* diff --git a/Projects/verification/screenshots_qt5142/01_converter.png b/Projects/verification/screenshots_qt5142/01_converter.png new file mode 100644 index 0000000..64fa4ce Binary files /dev/null and b/Projects/verification/screenshots_qt5142/01_converter.png differ diff --git a/Projects/verification/screenshots_qt5142/02_timer.png b/Projects/verification/screenshots_qt5142/02_timer.png new file mode 100644 index 0000000..8266403 Binary files /dev/null and b/Projects/verification/screenshots_qt5142/02_timer.png differ diff --git a/Projects/verification/screenshots_qt5142/03_groups.png b/Projects/verification/screenshots_qt5142/03_groups.png new file mode 100644 index 0000000..c217c52 Binary files /dev/null and b/Projects/verification/screenshots_qt5142/03_groups.png differ diff --git a/Projects/verification/screenshots_qt5142/03_raffle.png b/Projects/verification/screenshots_qt5142/03_raffle.png new file mode 100644 index 0000000..e091f5f Binary files /dev/null and b/Projects/verification/screenshots_qt5142/03_raffle.png differ diff --git a/Projects/verification/验证说明.md b/Projects/verification/验证说明.md new file mode 100644 index 0000000..97aec85 --- /dev/null +++ b/Projects/verification/验证说明.md @@ -0,0 +1,32 @@ +# 构建与验证记录 + +验证日期:2026-11-05。 + +## 实际运行的版本 + +| 环境 | 构建方式 | C++ 标准 | 结果 | +|---|---|---|---| +| Qt 5.14.2 / MinGW 7.3.0 64 位 | CMake 3.30.5 + Ninja | C++14 | 三个应用构建通过,三组测试通过 | +| Qt 6.8.3 / MinGW 13.1.0 64 位 | CMake 3.30.5 + Ninja | C++17 | 三个应用构建通过,三组测试通过 | +| 本机 Qt 6.8.3 / MinGW 13.1.0 | qmake + mingw32-make | C++17 | 三个 .pro 工程构建通过 | + +Qt 5.14.2 使用 Qt 官方归档中的 Qt Base 与匹配的 MinGW 7.3 工具链,下载包已对照官方 SHA-1 校验。Qt 6.8.3 使用本机 D:/Qt 中的 Kit。 + +独立 Qt 5.14.2 归档中的 qmake 在许可检查阶段停止,因此本次不宣称 Qt 5 的 qmake 构建已经通过,也没有修改许可检查。Qt 5.14.2 的兼容性验证来自真实的 CMake 编译、链接和测试运行。交付的 .pro 使用常规 Widgets、FORMS 和 C++14 配置,并已在本机 Qt 6 的 qmake 中验证。 + +## 自动化测试范围 + +- 单位换算:12 组已知结果、绝对零度边界、非法文本、负长度、溢出,以及换算、切换类型、交换单位和清除旧结果的界面流程。 +- 计时器:连续点击开始、暂停与继续、延迟刷新、截止时刻暂停、复位、零时长,以及界面上的真实计时过程。 +- 抽签与分组:空名单、重复条目、同名不同学号、不重复抽签、候选池重置;对 1—100 人分别验证两种分组方式,检查总人数、唯一性、人数上限和组间人数差;检查编辑名单后的按钮与结果状态。 + +每个 Qt 版本的 Qt Test 报告分别记为 16、6、6 项通过,其中包含初始化和清理项。全部测试均无失败。逐项结果保存在同目录的六个 qt5142_*.txt / qt683_*.txt 文件中。 + +## 界面和运行库 + +Qt 5.14.2 的四张截图保存在 screenshots_qt5142,覆盖单位换算、课堂计时、抽签和分组页面。已逐张查看中文显示、按钮文字、布局和结果区域。 + +Run_Qt5.14.2 中包含三个 Release EXE、Qt Core/Gui/Widgets、Windows 平台插件及匹配的 MinGW 运行库。启动验证时从进程 PATH 中移除 Qt 与编译器目录,使用 Windows 平台创建窗口,并向本次启动的进程发送正常关闭消息。三个程序均退出为 0,记录见 portable_smoke.txt。 + +本次没有使用 QML 或 Qt Quick,也没有打开浏览器进行检查。验证范围为本机 Windows 64 位;系统提示音是否可听见仍取决于系统声音设置。 + diff --git a/Qt6 C++ 开发指南.pdf b/Qt6 C++ 开发指南.pdf new file mode 100644 index 0000000..7a32834 Binary files /dev/null and b/Qt6 C++ 开发指南.pdf differ diff --git a/第01章_认识Qt/第01章_认识Qt.pptx b/第01章_认识Qt/第01章_认识Qt.pptx new file mode 100644 index 0000000..fdf068f Binary files /dev/null and b/第01章_认识Qt/第01章_认识Qt.pptx differ diff --git a/第02章_GUI程序设计基础/第02章_2.1_GUI程序结构与运行机制.pptx b/第02章_GUI程序设计基础/第02章_2.1_GUI程序结构与运行机制.pptx new file mode 100644 index 0000000..9a2c558 Binary files /dev/null and b/第02章_GUI程序设计基础/第02章_2.1_GUI程序结构与运行机制.pptx differ diff --git a/第02章_GUI程序设计基础/第02章_2.2_可视化UI设计_布局与信号槽.pptx b/第02章_GUI程序设计基础/第02章_2.2_可视化UI设计_布局与信号槽.pptx new file mode 100644 index 0000000..51ec86f Binary files /dev/null and b/第02章_GUI程序设计基础/第02章_2.2_可视化UI设计_布局与信号槽.pptx differ diff --git a/第02章_GUI程序设计基础/第02章_2.3-2.5_代码化UI设计_CMake构建与QtCreator技巧.pptx b/第02章_GUI程序设计基础/第02章_2.3-2.5_代码化UI设计_CMake构建与QtCreator技巧.pptx new file mode 100644 index 0000000..1054393 Binary files /dev/null and b/第02章_GUI程序设计基础/第02章_2.3-2.5_代码化UI设计_CMake构建与QtCreator技巧.pptx differ diff --git a/第03章_Qt框架功能概述/第03章_3.1-3.3.3_模块_全局定义与元对象基础.pptx b/第03章_Qt框架功能概述/第03章_3.1-3.3.3_模块_全局定义与元对象基础.pptx new file mode 100644 index 0000000..17b6184 Binary files /dev/null and b/第03章_Qt框架功能概述/第03章_3.1-3.3.3_模块_全局定义与元对象基础.pptx differ diff --git a/第03章_Qt框架功能概述/第03章_3.3.4-3.3.6_信号槽_对象树与综合示例.pptx b/第03章_Qt框架功能概述/第03章_3.3.4-3.3.6_信号槽_对象树与综合示例.pptx new file mode 100644 index 0000000..f12aa1b Binary files /dev/null and b/第03章_Qt框架功能概述/第03章_3.3.4-3.3.6_信号槽_对象树与综合示例.pptx differ diff --git a/第03章_Qt框架功能概述/第03章_3.4-3.5_容器类与常用基础类.pptx b/第03章_Qt框架功能概述/第03章_3.4-3.5_容器类与常用基础类.pptx new file mode 100644 index 0000000..51b20bb Binary files /dev/null and b/第03章_Qt框架功能概述/第03章_3.4-3.5_容器类与常用基础类.pptx differ diff --git a/第04章_常用界面组件的使用/第04章_4.1-4.2_界面组件与布局管理.pptx b/第04章_常用界面组件的使用/第04章_4.1-4.2_界面组件与布局管理.pptx new file mode 100644 index 0000000..72db423 Binary files /dev/null and b/第04章_常用界面组件的使用/第04章_4.1-4.2_界面组件与布局管理.pptx differ diff --git a/第04章_常用界面组件的使用/第04章_4.10_主窗口_QAction与文本编辑.pptx b/第04章_常用界面组件的使用/第04章_4.10_主窗口_QAction与文本编辑.pptx new file mode 100644 index 0000000..b46cb44 Binary files /dev/null and b/第04章_常用界面组件的使用/第04章_4.10_主窗口_QAction与文本编辑.pptx differ diff --git a/第04章_常用界面组件的使用/第04章_4.11_工具按钮与QListWidget.pptx b/第04章_常用界面组件的使用/第04章_4.11_工具按钮与QListWidget.pptx new file mode 100644 index 0000000..8e2f0ea Binary files /dev/null and b/第04章_常用界面组件的使用/第04章_4.11_工具按钮与QListWidget.pptx differ diff --git a/第04章_常用界面组件的使用/第04章_4.12_QTreeWidget_图片显示与停靠窗口.pptx b/第04章_常用界面组件的使用/第04章_4.12_QTreeWidget_图片显示与停靠窗口.pptx new file mode 100644 index 0000000..f849861 Binary files /dev/null and b/第04章_常用界面组件的使用/第04章_4.12_QTreeWidget_图片显示与停靠窗口.pptx differ diff --git a/第04章_常用界面组件的使用/第04章_4.13_QTableWidget_表格操作.pptx b/第04章_常用界面组件的使用/第04章_4.13_QTableWidget_表格操作.pptx new file mode 100644 index 0000000..fb19be3 Binary files /dev/null and b/第04章_常用界面组件的使用/第04章_4.13_QTableWidget_表格操作.pptx differ diff --git a/第04章_常用界面组件的使用/第04章_4.3_QString与QChar_字符串操作.pptx b/第04章_常用界面组件的使用/第04章_4.3_QString与QChar_字符串操作.pptx new file mode 100644 index 0000000..4e83878 Binary files /dev/null and b/第04章_常用界面组件的使用/第04章_4.3_QString与QChar_字符串操作.pptx differ diff --git a/第04章_常用界面组件的使用/第04章_4.4-4.6_数值输入_按钮与滑动组件.pptx b/第04章_常用界面组件的使用/第04章_4.4-4.6_数值输入_按钮与滑动组件.pptx new file mode 100644 index 0000000..ef3132b Binary files /dev/null and b/第04章_常用界面组件的使用/第04章_4.4-4.6_数值输入_按钮与滑动组件.pptx differ diff --git a/第04章_常用界面组件的使用/第04章_4.7-4.9_日期时间_定时器与下拉列表.pptx b/第04章_常用界面组件的使用/第04章_4.7-4.9_日期时间_定时器与下拉列表.pptx new file mode 100644 index 0000000..84725cf Binary files /dev/null and b/第04章_常用界面组件的使用/第04章_4.7-4.9_日期时间_定时器与下拉列表.pptx differ diff --git a/第05章_模型与视图结构/第05章_5.1_模型与视图基础.pptx b/第05章_模型与视图结构/第05章_5.1_模型与视图基础.pptx new file mode 100644 index 0000000..12f5c29 Binary files /dev/null and b/第05章_模型与视图结构/第05章_5.1_模型与视图基础.pptx differ diff --git a/第05章_模型与视图结构/第05章_5.2_QStringListModel_字符串列表.pptx b/第05章_模型与视图结构/第05章_5.2_QStringListModel_字符串列表.pptx new file mode 100644 index 0000000..b6a237e Binary files /dev/null and b/第05章_模型与视图结构/第05章_5.2_QStringListModel_字符串列表.pptx differ diff --git a/第05章_模型与视图结构/第05章_5.3_QStandardItemModel_表格与选择.pptx b/第05章_模型与视图结构/第05章_5.3_QStandardItemModel_表格与选择.pptx new file mode 100644 index 0000000..38ac650 Binary files /dev/null and b/第05章_模型与视图结构/第05章_5.3_QStandardItemModel_表格与选择.pptx differ diff --git a/第05章_模型与视图结构/第05章_5.4_自定义代理.pptx b/第05章_模型与视图结构/第05章_5.4_自定义代理.pptx new file mode 100644 index 0000000..36e62ef Binary files /dev/null and b/第05章_模型与视图结构/第05章_5.4_自定义代理.pptx differ diff --git a/第05章_模型与视图结构/第05章_5.5_QFileSystemModel_文件浏览.pptx b/第05章_模型与视图结构/第05章_5.5_QFileSystemModel_文件浏览.pptx new file mode 100644 index 0000000..f50e3a6 Binary files /dev/null and b/第05章_模型与视图结构/第05章_5.5_QFileSystemModel_文件浏览.pptx differ diff --git a/第06章_事件处理/第06章_6.1_Qt的事件系统.pptx b/第06章_事件处理/第06章_6.1_Qt的事件系统.pptx new file mode 100644 index 0000000..42036e3 Binary files /dev/null and b/第06章_事件处理/第06章_6.1_Qt的事件系统.pptx differ diff --git a/第06章_事件处理/第06章_6.2_事件与信号.pptx b/第06章_事件处理/第06章_6.2_事件与信号.pptx new file mode 100644 index 0000000..07e0ac6 Binary files /dev/null and b/第06章_事件处理/第06章_6.2_事件与信号.pptx differ diff --git a/第06章_事件处理/第06章_6.3_事件过滤器.pptx b/第06章_事件处理/第06章_6.3_事件过滤器.pptx new file mode 100644 index 0000000..e7fb24b Binary files /dev/null and b/第06章_事件处理/第06章_6.3_事件过滤器.pptx differ diff --git a/第06章_事件处理/第06章_6.4_拖放事件与拖放操作.pptx b/第06章_事件处理/第06章_6.4_拖放事件与拖放操作.pptx new file mode 100644 index 0000000..76d026e Binary files /dev/null and b/第06章_事件处理/第06章_6.4_拖放事件与拖放操作.pptx differ diff --git a/第06章_事件处理/第06章_6.5_具有拖放功能的组件.pptx b/第06章_事件处理/第06章_6.5_具有拖放功能的组件.pptx new file mode 100644 index 0000000..a955387 Binary files /dev/null and b/第06章_事件处理/第06章_6.5_具有拖放功能的组件.pptx differ diff --git a/第07章_对话框和多窗口程序设计/第07章_7.1.1-7.1.3_文件与外观标准对话框.pptx b/第07章_对话框和多窗口程序设计/第07章_7.1.1-7.1.3_文件与外观标准对话框.pptx new file mode 100644 index 0000000..858e7bf Binary files /dev/null and b/第07章_对话框和多窗口程序设计/第07章_7.1.1-7.1.3_文件与外观标准对话框.pptx differ diff --git a/第07章_对话框和多窗口程序设计/第07章_7.1.4-7.1.6_进度输入与消息对话框.pptx b/第07章_对话框和多窗口程序设计/第07章_7.1.4-7.1.6_进度输入与消息对话框.pptx new file mode 100644 index 0000000..4f80976 Binary files /dev/null and b/第07章_对话框和多窗口程序设计/第07章_7.1.4-7.1.6_进度输入与消息对话框.pptx differ diff --git a/第07章_对话框和多窗口程序设计/第07章_7.2.1-7.2.5_自定义对话框与设置提交.pptx b/第07章_对话框和多窗口程序设计/第07章_7.2.1-7.2.5_自定义对话框与设置提交.pptx new file mode 100644 index 0000000..079c04d Binary files /dev/null and b/第07章_对话框和多窗口程序设计/第07章_7.2.1-7.2.5_自定义对话框与设置提交.pptx differ diff --git a/第07章_对话框和多窗口程序设计/第07章_7.2.6_非模态定位与窗口交互.pptx b/第07章_对话框和多窗口程序设计/第07章_7.2.6_非模态定位与窗口交互.pptx new file mode 100644 index 0000000..ca71aaf Binary files /dev/null and b/第07章_对话框和多窗口程序设计/第07章_7.2.6_非模态定位与窗口交互.pptx differ diff --git a/第07章_对话框和多窗口程序设计/第07章_7.3_多窗口应用程序设计.pptx b/第07章_对话框和多窗口程序设计/第07章_7.3_多窗口应用程序设计.pptx new file mode 100644 index 0000000..cc9a208 Binary files /dev/null and b/第07章_对话框和多窗口程序设计/第07章_7.3_多窗口应用程序设计.pptx differ diff --git a/第07章_对话框和多窗口程序设计/第07章_7.4_MDI应用程序设计.pptx b/第07章_对话框和多窗口程序设计/第07章_7.4_MDI应用程序设计.pptx new file mode 100644 index 0000000..bd00dc1 Binary files /dev/null and b/第07章_对话框和多窗口程序设计/第07章_7.4_MDI应用程序设计.pptx differ diff --git a/第07章_对话框和多窗口程序设计/第07章_7.5_Splash与登录窗口.pptx b/第07章_对话框和多窗口程序设计/第07章_7.5_Splash与登录窗口.pptx new file mode 100644 index 0000000..2c44aae Binary files /dev/null and b/第07章_对话框和多窗口程序设计/第07章_7.5_Splash与登录窗口.pptx differ diff --git a/第08章_文件系统操作和文件读写/第08章_8.1-8.2.5_文件操作类与目录管理.pptx b/第08章_文件系统操作和文件读写/第08章_8.1-8.2.5_文件操作类与目录管理.pptx new file mode 100644 index 0000000..e80606e Binary files /dev/null and b/第08章_文件系统操作和文件读写/第08章_8.1-8.2.5_文件操作类与目录管理.pptx differ diff --git a/第08章_文件系统操作和文件读写/第08章_8.2.6-8.2.8_临时文件与文件系统监视.pptx b/第08章_文件系统操作和文件读写/第08章_8.2.6-8.2.8_临时文件与文件系统监视.pptx new file mode 100644 index 0000000..ffe54b6 Binary files /dev/null and b/第08章_文件系统操作和文件读写/第08章_8.2.6-8.2.8_临时文件与文件系统监视.pptx differ diff --git a/第08章_文件系统操作和文件读写/第08章_8.3_文本文件读写与安全保存.pptx b/第08章_文件系统操作和文件读写/第08章_8.3_文本文件读写与安全保存.pptx new file mode 100644 index 0000000..426c397 Binary files /dev/null and b/第08章_文件系统操作和文件读写/第08章_8.3_文本文件读写与安全保存.pptx differ diff --git a/第08章_文件系统操作和文件读写/第08章_8.4.1-8.4.3_QDataStream预定义编码.pptx b/第08章_文件系统操作和文件读写/第08章_8.4.1-8.4.3_QDataStream预定义编码.pptx new file mode 100644 index 0000000..ce9d595 Binary files /dev/null and b/第08章_文件系统操作和文件读写/第08章_8.4.1-8.4.3_QDataStream预定义编码.pptx differ diff --git a/第08章_文件系统操作和文件读写/第08章_8.4.4_原始二进制读写与文件格式.pptx b/第08章_文件系统操作和文件读写/第08章_8.4.4_原始二进制读写与文件格式.pptx new file mode 100644 index 0000000..752cc0b Binary files /dev/null and b/第08章_文件系统操作和文件读写/第08章_8.4.4_原始二进制读写与文件格式.pptx differ diff --git a/第09章_数据库/第09章_9.1_数据库基础与连接管理.pptx b/第09章_数据库/第09章_9.1_数据库基础与连接管理.pptx new file mode 100644 index 0000000..41b687f Binary files /dev/null and b/第09章_数据库/第09章_9.1_数据库基础与连接管理.pptx differ diff --git a/第09章_数据库/第09章_9.2_QSqlTableModel与编辑提交.pptx b/第09章_数据库/第09章_9.2_QSqlTableModel与编辑提交.pptx new file mode 100644 index 0000000..e87e5e2 Binary files /dev/null and b/第09章_数据库/第09章_9.2_QSqlTableModel与编辑提交.pptx differ diff --git a/第09章_数据库/第09章_9.3_QSqlQueryModel与查询显示.pptx b/第09章_数据库/第09章_9.3_QSqlQueryModel与查询显示.pptx new file mode 100644 index 0000000..2813d12 Binary files /dev/null and b/第09章_数据库/第09章_9.3_QSqlQueryModel与查询显示.pptx differ diff --git a/第09章_数据库/第09章_9.4_QSqlQuery与SQL操作.pptx b/第09章_数据库/第09章_9.4_QSqlQuery与SQL操作.pptx new file mode 100644 index 0000000..e65569a Binary files /dev/null and b/第09章_数据库/第09章_9.4_QSqlQuery与SQL操作.pptx differ diff --git a/第09章_数据库/第09章_9.5_关联模型与数据表关系.pptx b/第09章_数据库/第09章_9.5_关联模型与数据表关系.pptx new file mode 100644 index 0000000..070983d Binary files /dev/null and b/第09章_数据库/第09章_9.5_关联模型与数据表关系.pptx differ diff --git a/第10章_绘图/第10章_10.1_QPainter基本绘图.pptx b/第10章_绘图/第10章_10.1_QPainter基本绘图.pptx new file mode 100644 index 0000000..50bcff1 Binary files /dev/null and b/第10章_绘图/第10章_10.1_QPainter基本绘图.pptx differ diff --git a/第10章_绘图/第10章_10.2_坐标系统与坐标变换.pptx b/第10章_绘图/第10章_10.2_坐标系统与坐标变换.pptx new file mode 100644 index 0000000..2bd1811 Binary files /dev/null and b/第10章_绘图/第10章_10.2_坐标系统与坐标变换.pptx differ diff --git a/第10章_绘图/第10章_10.3_图形视图架构与坐标交互.pptx b/第10章_绘图/第10章_10.3_图形视图架构与坐标交互.pptx new file mode 100644 index 0000000..8f957b6 Binary files /dev/null and b/第10章_绘图/第10章_10.3_图形视图架构与坐标交互.pptx differ diff --git a/第10章_绘图/第10章_10.4_01_图像表示与QImage.pptx b/第10章_绘图/第10章_10.4_01_图像表示与QImage.pptx new file mode 100644 index 0000000..94886da Binary files /dev/null and b/第10章_绘图/第10章_10.4_01_图像表示与QImage.pptx differ diff --git a/第10章_绘图/第10章_10.4_02_图像处理示例与RGB565导出.pptx b/第10章_绘图/第10章_10.4_02_图像处理示例与RGB565导出.pptx new file mode 100644 index 0000000..1afcdf1 Binary files /dev/null and b/第10章_绘图/第10章_10.4_02_图像处理示例与RGB565导出.pptx differ diff --git a/第10章_绘图/第10章_10.4_03_打印预览与打印.pptx b/第10章_绘图/第10章_10.4_03_打印预览与打印.pptx new file mode 100644 index 0000000..43ec7ab Binary files /dev/null and b/第10章_绘图/第10章_10.4_03_打印预览与打印.pptx differ diff --git a/第11章_自定义插件和库/第11章_11.1-11.2_自定义组件与Designer插件.pptx b/第11章_自定义插件和库/第11章_11.1-11.2_自定义组件与Designer插件.pptx new file mode 100644 index 0000000..da1c881 Binary files /dev/null and b/第11章_自定义插件和库/第11章_11.1-11.2_自定义组件与Designer插件.pptx differ diff --git a/第11章_自定义插件和库/第11章_11.3-11.4_静态库与共享库.pptx b/第11章_自定义插件和库/第11章_11.3-11.4_静态库与共享库.pptx new file mode 100644 index 0000000..91e80e5 Binary files /dev/null and b/第11章_自定义插件和库/第11章_11.3-11.4_静态库与共享库.pptx differ diff --git a/第12章_Qt Charts二维图表/第12章_12.1-12.2_图表结构与折线图.pptx b/第12章_Qt Charts二维图表/第12章_12.1-12.2_图表结构与折线图.pptx new file mode 100644 index 0000000..bbb679b Binary files /dev/null and b/第12章_Qt Charts二维图表/第12章_12.1-12.2_图表结构与折线图.pptx differ diff --git a/第12章_Qt Charts二维图表/第12章_12.3_图表交互操作.pptx b/第12章_Qt Charts二维图表/第12章_12.3_图表交互操作.pptx new file mode 100644 index 0000000..ffc94d2 Binary files /dev/null and b/第12章_Qt Charts二维图表/第12章_12.3_图表交互操作.pptx differ diff --git a/第12章_Qt Charts二维图表/第12章_12.4_柱状图_百分比图与饼图.pptx b/第12章_Qt Charts二维图表/第12章_12.4_柱状图_百分比图与饼图.pptx new file mode 100644 index 0000000..353fc6e Binary files /dev/null and b/第12章_Qt Charts二维图表/第12章_12.4_柱状图_百分比图与饼图.pptx differ diff --git a/第13章_Qt Data Visualization三维数据可视化/第13章_13.1-13.2_三维图表结构与柱状图.pptx b/第13章_Qt Data Visualization三维数据可视化/第13章_13.1-13.2_三维图表结构与柱状图.pptx new file mode 100644 index 0000000..cf87845 Binary files /dev/null and b/第13章_Qt Data Visualization三维数据可视化/第13章_13.1-13.2_三维图表结构与柱状图.pptx differ diff --git a/第13章_Qt Data Visualization三维数据可视化/第13章_13.3_三维散点图与点数据管理.pptx b/第13章_Qt Data Visualization三维数据可视化/第13章_13.3_三维散点图与点数据管理.pptx new file mode 100644 index 0000000..25f2d3e Binary files /dev/null and b/第13章_Qt Data Visualization三维数据可视化/第13章_13.3_三维散点图与点数据管理.pptx differ diff --git a/第13章_Qt Data Visualization三维数据可视化/第13章_13.4_三维曲面与高度图地形.pptx b/第13章_Qt Data Visualization三维数据可视化/第13章_13.4_三维曲面与高度图地形.pptx new file mode 100644 index 0000000..8c706cb Binary files /dev/null and b/第13章_Qt Data Visualization三维数据可视化/第13章_13.4_三维曲面与高度图地形.pptx differ diff --git a/第14章_多线程/第14章_14.1_QThread运行与安全停止.pptx b/第14章_多线程/第14章_14.1_QThread运行与安全停止.pptx new file mode 100644 index 0000000..ccd8744 Binary files /dev/null and b/第14章_多线程/第14章_14.1_QThread运行与安全停止.pptx differ diff --git a/第14章_多线程/第14章_14.2_01_线程同步_互斥量与读写锁.pptx b/第14章_多线程/第14章_14.2_01_线程同步_互斥量与读写锁.pptx new file mode 100644 index 0000000..449031f Binary files /dev/null and b/第14章_多线程/第14章_14.2_01_线程同步_互斥量与读写锁.pptx differ diff --git a/第14章_多线程/第14章_14.2_02_线程同步_条件等待与信号量.pptx b/第14章_多线程/第14章_14.2_02_线程同步_条件等待与信号量.pptx new file mode 100644 index 0000000..3028019 Binary files /dev/null and b/第14章_多线程/第14章_14.2_02_线程同步_条件等待与信号量.pptx differ diff --git a/第15章_网络/第15章_15.1_主机信息查询与网络接口.pptx b/第15章_网络/第15章_15.1_主机信息查询与网络接口.pptx new file mode 100644 index 0000000..9576aa7 Binary files /dev/null and b/第15章_网络/第15章_15.1_主机信息查询与网络接口.pptx differ diff --git a/第15章_网络/第15章_15.2_TCP通信_服务器客户端与字节流.pptx b/第15章_网络/第15章_15.2_TCP通信_服务器客户端与字节流.pptx new file mode 100644 index 0000000..878fd0b Binary files /dev/null and b/第15章_网络/第15章_15.2_TCP通信_服务器客户端与字节流.pptx differ diff --git a/第15章_网络/第15章_15.3_UDP通信_单播广播与组播.pptx b/第15章_网络/第15章_15.3_UDP通信_单播广播与组播.pptx new file mode 100644 index 0000000..86b8d4f Binary files /dev/null and b/第15章_网络/第15章_15.3_UDP通信_单播广播与组播.pptx differ diff --git a/第15章_网络/第15章_15.4_HTTP下载_异步响应与完整保存.pptx b/第15章_网络/第15章_15.4_HTTP下载_异步响应与完整保存.pptx new file mode 100644 index 0000000..eb37eb5 Binary files /dev/null and b/第15章_网络/第15章_15.4_HTTP下载_异步响应与完整保存.pptx differ diff --git a/第16章_多媒体/第16章_16.1-16.2_多媒体对象与音频播放.pptx b/第16章_多媒体/第16章_16.1-16.2_多媒体对象与音频播放.pptx new file mode 100644 index 0000000..e1675cc Binary files /dev/null and b/第16章_多媒体/第16章_16.1-16.2_多媒体对象与音频播放.pptx differ diff --git a/第16章_多媒体/第16章_16.3_麦克风录音_参数设置与输出检查.pptx b/第16章_多媒体/第16章_16.3_麦克风录音_参数设置与输出检查.pptx new file mode 100644 index 0000000..1403ca7 Binary files /dev/null and b/第16章_多媒体/第16章_16.3_麦克风录音_参数设置与输出检查.pptx differ diff --git a/第16章_多媒体/第16章_16.4_原始PCM_采集显示与回放.pptx b/第16章_多媒体/第16章_16.4_原始PCM_采集显示与回放.pptx new file mode 100644 index 0000000..e5350a5 Binary files /dev/null and b/第16章_多媒体/第16章_16.4_原始PCM_采集显示与回放.pptx differ diff --git a/第16章_多媒体/第16章_16.5-16.6_视频播放_摄像头拍照与录像.pptx b/第16章_多媒体/第16章_16.5-16.6_视频播放_摄像头拍照与录像.pptx new file mode 100644 index 0000000..d4b512f Binary files /dev/null and b/第16章_多媒体/第16章_16.5-16.6_视频播放_摄像头拍照与录像.pptx differ diff --git a/第17章_串口编程/第17章_17.1-17.2_串口通信与ESP8266命令流程.pptx b/第17章_串口编程/第17章_17.1-17.2_串口通信与ESP8266命令流程.pptx new file mode 100644 index 0000000..2e22a8c Binary files /dev/null and b/第17章_串口编程/第17章_17.1-17.2_串口通信与ESP8266命令流程.pptx differ diff --git a/第18章_其他工具软件和技术(多语言、样式表与发布安装)/第18章_18.1_多语言界面_提取翻译与运行时切换.pptx b/第18章_其他工具软件和技术(多语言、样式表与发布安装)/第18章_18.1_多语言界面_提取翻译与运行时切换.pptx new file mode 100644 index 0000000..9bb9357 Binary files /dev/null and b/第18章_其他工具软件和技术(多语言、样式表与发布安装)/第18章_18.1_多语言界面_提取翻译与运行时切换.pptx differ diff --git a/第18章_其他工具软件和技术(多语言、样式表与发布安装)/第18章_18.2_Qt样式表_选择器冲突与主题切换.pptx b/第18章_其他工具软件和技术(多语言、样式表与发布安装)/第18章_18.2_Qt样式表_选择器冲突与主题切换.pptx new file mode 100644 index 0000000..f17ede0 Binary files /dev/null and b/第18章_其他工具软件和技术(多语言、样式表与发布安装)/第18章_18.2_Qt样式表_选择器冲突与主题切换.pptx differ diff --git a/第18章_其他工具软件和技术(多语言、样式表与发布安装)/第18章_18.3_Windows发布_运行依赖与安装程序.pptx b/第18章_其他工具软件和技术(多语言、样式表与发布安装)/第18章_18.3_Windows发布_运行依赖与安装程序.pptx new file mode 100644 index 0000000..326e6fd Binary files /dev/null and b/第18章_其他工具软件和技术(多语言、样式表与发布安装)/第18章_18.3_Windows发布_运行依赖与安装程序.pptx differ