#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())); }