• qt功能自己创作


    按钮按下三秒禁用

    1. void MainWindow::on_pushButton_5_clicked()
    2. {
    3.     // 锁定界面
    4.     setWidgetsEnabled(ui->centralwidget, false);
    5.     // 创建一个定时器,等待3秒后解锁界面
    6.     QTimer::singleShot(3000, this, [=]() {
    7.         setWidgetsEnabled(ui->centralwidget, true);;//ui->centralwidget这个是全局布局
    8.     });
    9. }
    10. // 将界面的所有控件禁用或启用
    11. void MainWindow::setWidgetsEnabled(QWidget *widget, bool enabled) {
    12.     if (widget) {
    13.         for (auto child : widget->findChildren()) {
    14.             if (child->isWidgetType()) {
    15.                 child->setEnabled(enabled);
    16.                 qDebug() << "Widget:" << child->objectName() << "Enabled:" << enabled;
    17.             }
    18.         }
    19.     }
    20. }

    读写配置文件 

    1. void MainWindow::read_init()
    2. {
    3. QSettings settings("myapp.ini", QSettings::IniFormat);
    4. if (!settings.contains("server/port")) {
    5. // 如果不存在,才写入配置项
    6. settings.setValue("server/port", "8080");
    7. }
    8. server_PortStr = settings.value("server/port").toString();
    9. qDebug() << "port:" << server_PortStr;
    10. }

    不同文件利用信号和槽通信

    发送方

    dialog.h

    1. signals:
    2. void dataEntered(const QString &data);

    dialog.c

    emit dataEntered(ipAddress);

    接收方

    mainwindow.h

    1. private slots:
    2. void receiveData(const QString &data);
    3. private:
    4. Dialog *dialog;

    mainwindow.cpp

    1. MainWindow::MainWindow(QWidget *parent)
    2. : QMainWindow(parent)
    3. , ui(new Ui::MainWindow)
    4. {
    5. ui->setupUi(this);
    6. dialog= new Dialog();
    7. connect(dialog, SIGNAL(dataEntered(QString)), this, SLOT(receiveData(QString)));
    8. }
    9. void MainWindow::receiveData(const QString &data) {
    10. // 在这里处理接收到的数据
    11. server_IP=data;
    12. qDebug() << "Received data in MainWindow:" << server_IP;
    13. //插入新行
    14. int currentRow = ui->tableWidget->rowCount();
    15. qDebug() << "currentRow" << currentRow;
    16. ui->tableWidget->insertRow(currentRow);
    17. // 创建一个 QTableWidgetItem 对象并设置文本
    18. QTableWidgetItem *item1 = new QTableWidgetItem(QString::number(currentRow + 1)); // 设置序号
    19. QTableWidgetItem *item2 = new QTableWidgetItem(server_IP); // 设置数据
    20. // 插入 QTableWidgetItem 到指定行和列
    21. ui->tableWidget->setItem(currentRow, 0, item1); // 设置第一列的单元格为序号
    22. ui->tableWidget->setItem(currentRow, 1, item2); // 设置第二列的单元格为数据
    23. }

    UDP通信

    1. void MainWindow::sendAndReceiveData(const QByteArray &sendData, QByteArray &receivedData, const QString &serverIP) {
    2. // 将字符串形式的端口号转换为整数
    3. bool ok;
    4. quint16 serverPort = server_PortStr.toUShort(&ok);
    5. if (!ok) {
    6. qDebug() << "Invalid port number:" << server_PortStr;
    7. return; // 如果端口号无效,函数直接返回
    8. }
    9. // 将字符串形式的IP地址转换为QHostAddress
    10. QHostAddress serverAddress(serverIP);
    11. // 发送数据到服务器
    12. udpSocket->writeDatagram(sendData, serverAddress, serverPort);
    13. // 接收服务器的回复
    14. QByteArray responseData;
    15. while (udpSocket->waitForReadyRead()) {
    16. responseData.resize(udpSocket->pendingDatagramSize());
    17. QHostAddress senderAddress;
    18. quint16 senderPort;
    19. udpSocket->readDatagram(responseData.data(), responseData.size(), &senderAddress, &senderPort);
    20. MainWindow::~MainWindow()
    21. {
    22. //关闭套接字,并丢弃写缓冲区中的所有待处理数据。
    23. // udpSocket->abort();
    24. delete ui;
    25. }
    26. // 将接收到的数据存储到传入的receivedData变量中
    27. receivedData = responseData;
    28. qDebug() << "Received response from server" << senderAddress.toString() << "on port" << senderPort;
    29. qDebug() << "Response Data:" << responseData;
    30. }
    31. }

    1. bool WorkThread::udpCommunicate(const QJsonObject &sendData,
    2. QJsonObject &receivedData,
    3. const QString &localIp,
    4. quint16 localPort,
    5. const QString &serverIp,
    6. quint16 serverPort)
    7. {
    8. // 创建 UDP 套接字
    9. QUdpSocket udpSocket;
    10. // 绑定本地 IP 和端口
    11. if (!udpSocket.bind(QHostAddress(localIp), localPort)) {
    12. qDebug() << "Failed to bind to local address and port";
    13. return false;
    14. }
    15. // 构造要发送的 JSON 数据
    16. QJsonDocument sendDoc(sendData);
    17. QByteArray sendByteArray = sendDoc.toJson(QJsonDocument::Compact);
    18. // 发送数据到服务器
    19. udpSocket.writeDatagram(sendByteArray, QHostAddress(serverIp), serverPort);
    20. while (true) {
    21. if (udpSocket.hasPendingDatagrams()) {
    22. QByteArray receivedByteArray;
    23. receivedByteArray.resize(udpSocket.pendingDatagramSize());
    24. udpSocket.readDatagram(receivedByteArray.data(), receivedByteArray.size());
    25. // 解析接收到的 JSON 数据
    26. QJsonParseError parseError;
    27. QJsonDocument receivedDoc = QJsonDocument::fromJson(receivedByteArray, &parseError);
    28. if (parseError.error != QJsonParseError::NoError) {
    29. qDebug() << "Failed to parse received JSON data:" << parseError.errorString();
    30. return false;
    31. }
    32. // 将接收到的 JSON 数据转换为 QJsonObject
    33. receivedData = receivedDoc.object();
    34. // 关闭套接字
    35. udpSocket.close();
    36. return true;
    37. }
    38. }
    39. }

    样式表使用方法

    在项目文件创建一个文件styles.qss,然后在qt资源文件打开现有文件即可

    然后代码加载;

    建议要用样式表都用样式表

    具体的样式比样式表级别高(具体样式背景影响样式表控件的样式)

    加载样式表在main函数里加载

    1. int main(int argc, char *argv[])
    2. {
    3. QApplication a(argc, argv);
    4. // 加载样式表文件
    5. QFile styleFile(":/new/styles.qss"); // 样式表文件的路径
    6. if (styleFile.open(QFile::ReadOnly | QFile::Text)) {
    7. QTextStream stream(&styleFile);
    8. QString style = stream.readAll();
    9. a.setStyleSheet(style); // 应用样式表
    10. styleFile.close();
    11. }
    12. MainWindow w;
    13. w.show();
    14. return a.exec();
    15. }

    多线程

    1. class WorkerThread : public QThread
    2. {
    3. Q_OBJECT
    4. public:
    5. WorkerThread() : shouldStop(false) {}
    6. void stopThread() {
    7. shouldStop = true;
    8. }
    9. protected:
    10. void run() override {
    11. //运行代码
    12. }
    13. private:
    14. bool shouldStop;
    15. };
    1. void MainWindow::on_pushButton_clicked()
    2. {
    3. // 创建 WorkerThread 对象并连接 finished 信号
    4. workerThread = new WorkerThread;
    5. QObject::connect(workerThread, &QThread::finished, [&]() {
    6. // 后台线程完成时设置按钮文本
    7. ui->pushButton->setEnabled(true);
    8. ui->pushButton->setText("刷新状态");
    9. // 释放 WorkerThread 对象
    10. workerThread->deleteLater();
    11. });
    12. // 点击按钮后设置按钮文本为 "刷新中..."
    13. ui->pushButton->setText("刷新中...");
    14. ui->pushButton->setEnabled(false);
    15. // 启动后台线程执行循环
    16. workerThread->start();
    17. }

    检测其它控件,并将本控件文本设置为灰色

    1. void MainWindow::on_pushButton_6_clicked()
    2. {
    3. // 获取选中的行
    4. int selectedRow = ui->tableWidget->currentRow();
    5. if (selectedRow >= 0) {
    6. // 检查第八列是否为空
    7. QTableWidgetItem *item8 = ui->tableWidget->item(selectedRow, 7); // 第八列索引为7
    8. bool isEmptyColumn8 = item8 && item8->text().isEmpty();
    9. // 检查其他列是否都不为空
    10. bool isOtherColumnsNotEmpty = true;
    11. for (int column = 0; column < ui->tableWidget->columnCount(); ++column) {
    12. if (column != 7) { // 排除第八列
    13. QTableWidgetItem *item = ui->tableWidget->item(selectedRow, column);
    14. if (!item || item->text().isEmpty()) {
    15. isOtherColumnsNotEmpty = false;
    16. break;
    17. }
    18. }
    19. }
    20. // 创建灰色文本颜色
    21. QColor grayColor = QColor("#8c8c8c");
    22. // 如果第八列为空且其他列都不为空,将第八列的数据设置为 "已启用" 并设置文本颜色为灰色
    23. if (isEmptyColumn8 && isOtherColumnsNotEmpty) {
    24. QTableWidgetItem *newItem = new QTableWidgetItem("已启用");
    25. newItem->setForeground(QBrush(grayColor)); // 设置文本颜色为灰色
    26. ui->tableWidget->setItem(selectedRow, 7, newItem);
    27. } else {
    28. QTableWidgetItem *newItem = new QTableWidgetItem("未启用");
    29. newItem->setForeground(QBrush(grayColor)); // 设置文本颜色为灰色
    30. ui->tableWidget->setItem(selectedRow, 7, newItem);
    31. }
    32. }
    33. }

    安卓写和加载临时文件

    1. // 获取临时文件的完整路径
    2. QString tempFilePath = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/temp_data.txt";
    3. // 在程序启动时加载临时文件中的数据
    4. void MainWidget::loadTempFileData() {
    5. QFile file(tempFilePath); // 使用完整路径
    6. if (file.exists()) {
    7. if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
    8. QTextStream in(&file);
    9. while (!in.atEnd()) {
    10. QString line = in.readLine();
    11. QStringList rowData = line.split(","); // 假设数据以逗号分隔
    12. if (rowData.size() == 3) {
    13. // 将每行数据添加到QTableWidget中的三列
    14. ui->tableWidget->insertRow(ui->tableWidget->rowCount());
    15. for (int column = 0; column < 3; ++column) {
    16. QTableWidgetItem *item = new QTableWidgetItem(rowData[column]);
    17. ui->tableWidget->setItem(ui->tableWidget->rowCount() - 1, column, item);
    18. }
    19. }
    20. }
    21. file.close();
    22. }
    23. }
    24. }
    25. // 在添加新行数据时,同时将所有数据写入临时文件
    26. void MainWidget::addRowToTableWidget(const QString &rowData) {
    27. // 将新行数据添加到QTableWidget中的三列
    28. ui->tableWidget->insertRow(ui->tableWidget->rowCount());
    29. QStringList rowDataList = rowData.split(","); // 使用逗号分隔字段
    30. for (int column = 0; column < 3; ++column) {
    31. if (column < rowDataList.size()) {
    32. QTableWidgetItem *item = new QTableWidgetItem(rowDataList[column]);
    33. ui->tableWidget->setItem(ui->tableWidget->rowCount() - 1, column, item);
    34. }
    35. }
    36. // 写入所有数据到临时文件
    37. QFile file(tempFilePath); // 使用完整路径
    38. if (file.open(QIODevice::WriteOnly | QIODevice::Text)) {
    39. QTextStream out(&file);
    40. // 遍历QTableWidget中的数据,将每行数据写入文件
    41. for (int row = 0; row < ui->tableWidget->rowCount(); ++row) {
    42. QStringList rowData;
    43. for (int column = 0; column < 3; ++column) {
    44. QTableWidgetItem *item = ui->tableWidget->item(row, column);
    45. if (item) {
    46. rowData << item->text();
    47. }
    48. }
    49. out << rowData.join(",") << "\n";
    50. }
    51. file.close();
    52. }
    53. }
    54. // 清空临时文件
    55. void MainWidget::clearTempFile() {
    56. QFile file(tempFilePath); // 使用完整路径
    57. if (file.exists()) {
    58. if (file.remove()) {
    59. qDebug() << "临时文件已成功清空.";
    60. } else {
    61. qDebug() << "无法清空临时文件.";
    62. }
    63. } else {
    64. qDebug() << "临时文件不存在.";
    65. }
    66. }

    定时器跳出循环

    1. #include
    2. #include
    3. #include
    4. int main(int argc, char *argv[]) {
    5. QCoreApplication a(argc, argv);
    6. // 创建一个定时器
    7. QTimer timer;
    8. timer.setSingleShot(true); // 设置定时器为单次触发
    9. timer.start(5000); // 设置超时时间为5秒
    10. // 使用事件循环等待定时器超时
    11. QEventLoop loop;
    12. QObject::connect(&timer, &QTimer::timeout, &loop, &QEventLoop::quit); // 当定时器超时时退出事件循环
    13. // 死循环,等待定时器超时
    14. while (true) {
    15. // 如果定时器超时,退出循环
    16. if (!timer.isActive()) {
    17. break;
    18. }
    19. // 处理其他任务
    20. // 这里可以添加需要执行的操作,确保不会阻塞事件循环
    21. // 处理事件,确保事件循环继续运行
    22. QCoreApplication::processEvents();
    23. }
    24. // 此处可以执行定时器超时后需要执行的操作
    25. return a.exec();
    26. }

    配置文件读写函数 

    1. void SystemManageWidget::writeini(const QString &key, const QString &value)
    2. {
    3. // 创建QSettings对象来操作配置文件
    4. const QString filePath="D:/devConfig.ini";
    5. QSettings settings(filePath, QSettings::IniFormat);
    6. // 在配置文件中创建一条信息
    7. settings.setValue(key, value);
    8. // 保存更改
    9. settings.sync();
    10. }
    11. QString SystemManageWidget::readini(const QString &key)
    12. {
    13. // 创建QSettings对象来操作配置文件
    14. const QString filePath = "D:/devConfig.ini";
    15. QSettings settings(filePath, QSettings::IniFormat);
    16. // 使用提供的键获取配置文件中的值
    17. return settings.value(key).toString();
    18. }

     UDP发送与处理

    1. void SystemManageWidget::UDP(QJsonObject &sendobj,QString &sever_ip){
    2. QJsonObject recv;
    3. QSettings *settings = new QSettings("D:/devConfig.ini", QSettings::Format::IniFormat);
    4. // ip=settings.value("ip").toString();
    5. QString client_port = settings->value("local_port").toString();
    6. QString Ui_port = settings->value("Ui_port").toString();
    7. QString client_ip=settings->value("client_ip").toString();
    8. QString severs_port=settings->value("UI_port").toString();
    9. qDebug()<<"severs_port"<
    10. qDebug()<<"client_port"<
    11. qDebug()<<"client_ip"<
    12. QByteArray send;
    13. QByteArray rec;
    14. QJsonDocument senddoc(sendobj);
    15. send=senddoc.toJson();
    16. QUdpSocket udp_socket;
    17. udp_socket.bind(QHostAddress(client_ip),client_port.toUShort());
    18. udp_socket.writeDatagram(send,QHostAddress(sever_ip),severs_port.toUShort());
    19. QHostAddress a;
    20. ushort aa;
    21. QTimer time;
    22. time.setSingleShot(true);
    23. time.start(5000);
    24. QEventLoop loop;
    25. connect(&time,&QTimer::timeout,&loop,&QEventLoop::quit);
    26. while(1){
    27. rec.resize(udp_socket.pendingDatagramSize());
    28. udp_socket.readDatagram(rec.data(),rec.size(),&a,&aa);
    29. if(!rec.isEmpty()){
    30. qDebug()<<"ip"<
    31. qDebug()<<"port"<
    32. qDebug()<<"size"<size();
    33. qDebug()<<"data"<data();
    34. QJsonDocument recdoc=QJsonDocument::fromJson(rec);
    35. recv=recdoc.object();
    36. break;
    37. }
    38. if (!time.isActive()) {
    39. qDebug() << "Timeout occurred."; // 超时处理
    40. break;
    41. }
    42. // 处理事件
    43. loop.processEvents();
    44. }
    45. //接收处理
    46. if(recv.contains("SystemMessage")&&recv["SystemMessage"].toBool()){}
    47. if(recv.contains("Reset")&&recv["Reset"].toBool()){}
    48. if(recv.contains("Restart")&&recv["Restart"].toBool()){}
    49. if(recv.contains("BackUp")){}
    50. }

    弹窗 

    1. QMessageBox::StandardButton reply;
    2. reply = QMessageBox::question(
    3. nullptr,
    4. "提示",
    5. "是否进行备份设置操作?",
    6. QMessageBox::Yes | QMessageBox::No
    7. );
    8. if (reply == QMessageBox::Yes) {
    9. } else {
    10. // 用户点击了取消按钮或关闭了弹窗,不执行备份设置操作
    11. }

    保存路径

    1. QString saveFilePath = QFileDialog::getSaveFileName(this, tr("选择保存位置"), "", tr("Batch Files (*.dat);;All Files (*)"));
    2. std::string filePath = saveFilePath.toStdString();
    3. std::string data1 = data.toStdString();
    4. if (!saveFilePath.isEmpty()) {
    5. // 打开文件以写入数据
    6. writeini("BackUpFilePath",saveFilePath);
    7. std::ofstream outputFile(filePath);
    8. if (outputFile.is_open()) {
    9. // 将数据写入文件
    10. outputFile << data1;
    11. // 关闭文件
    12. outputFile.close();
    13. std::cout << "数据已成功写入文件:" << filePath << std::endl;
    14. } else {
    15. std::cerr << "无法打开文件:" << filePath << std::endl;
    16. }
    17. }

    弹窗1

    1. void showSuccessMessage(const QString &title, const QString &message)
    2. {
    3. QMessageBox messageBox;
    4. messageBox.setIcon(QMessageBox::Information);
    5. messageBox.setWindowTitle(title);
    6. messageBox.setText(message);
    7. messageBox.setStandardButtons(QMessageBox::Ok);
    8. messageBox.exec();
    9. }

    弹窗2

    1. #include
    2. int showCustomConfirmationDialog(const QString &title, const QString &message, const QString &okButtonText, const QString &cancelButtonText)
    3. {
    4. QMessageBox messageBox;
    5. messageBox.setIcon(QMessageBox::Warning);
    6. messageBox.setWindowTitle(title);
    7. messageBox.setText(message);
    8. messageBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
    9. messageBox.setButtonText(QMessageBox::Ok, okButtonText);
    10. messageBox.setButtonText(QMessageBox::Cancel, cancelButtonText);
    11. return messageBox.exec();
    12. }
    13. // 使用示例
    14. void yourFunction()
    15. {
    16. int choice = showCustomConfirmationDialog("自定义标题", "您确定要执行此操作吗?", "确认", "取消");
    17. if (choice == QMessageBox::Ok) {
    18. // 用户点击了确认按钮,执行相关操作
    19. // 在这里添加您的操作代码
    20. } else if (choice == QMessageBox::Cancel) {
    21. // 用户点击了取消按钮,执行其他操作
    22. // 在这里添加您的操作代码
    23. }
    24. }

    3s弹窗

    1. #include
    2. #include
    3. // ...
    4. void SystemManageWidget::showTemporaryMessageBox(QString a)
    5. {
    6. QMessageBox messageBox;
    7. messageBox.setIcon(QMessageBox::Information); // 设置图标为信息图标
    8. messageBox.setWindowTitle(""); // 设置对话框标题
    9. messageBox.setText(a); // 设置消息文本
    10. QTimer timer;
    11. timer.setSingleShot(true); // 设置为单次触发
    12. timer.setInterval(3000); // 设置定时器间隔为3秒(3000毫秒)
    13. QObject::connect(&timer, &QTimer::timeout, [&messageBox]() {
    14. messageBox.close(); // 定时器触发后关闭消息框
    15. });
    16. messageBox.show(); // 显示消息框
    17. timer.start(); // 启动定时器
    18. Delay(3000);
    19. }
    20. void SystemManageWidget::Delay(int msec)
    21. { // 这个最准
    22. /*非阻塞方式延时,现在很多人推荐的方法*/
    23. QEventLoop loop;
    24. QTimer::singleShot(msec, &loop, SLOT(quit()));
    25. loop.exec();
    26. }

     选择文件路径

    1. #include
    2. // ...
    3. QString filePath = QFileDialog::getOpenFileName(this, "选择文件", "", "所有文件 (*.*);;文本文件 (*.txt);;图像文件 (*.png *.jpg)");
    4. if (!filePath.isEmpty()) {
    5. // 用户选择了文件,filePath包含所选文件的路径
    6. // 在这里可以对所选文件执行操作
    7. } else {
    8. // 用户取消了选择操作
    9. }

    将tablewight所有内容导出与导入

    1. void GeneralPolicyWidget::on_pushButton_3_clicked()
    2. {
    3. QString filePath = QFileDialog::getOpenFileName(this, "选择文件", "", tr("Batch Files (*.csv);;All Files (*)"));
    4. importCSVToTableWidget(filePath,ui->tableWidget);
    5. }
    6. void GeneralPolicyWidget::on_pushButton_4_clicked()
    7. {
    8. QString saveFilePath = QFileDialog::getSaveFileName(this, tr("选择保存位置"), "", tr("Batch Files (*.csv);;All Files (*)"));
    9. exportTableWidgetToCSV(ui->tableWidget,saveFilePath);
    10. }
    11. void GeneralPolicyWidget::exportTableWidgetToCSV(QTableWidget *tableWidget, const QString &filePath)
    12. {
    13. QFile file(filePath);
    14. if (file.open(QIODevice::WriteOnly | QIODevice::Text))
    15. {
    16. QTextStream stream(&file);
    17. // 写入表头
    18. QStringList headers;
    19. for (int col = 0; col < tableWidget->columnCount(); col++)
    20. {
    21. headers << tableWidget->horizontalHeaderItem(col)->text();
    22. }
    23. stream << headers.join(",") << "\n";
    24. // 写入表格数据
    25. for (int row = 0; row < tableWidget->rowCount(); row++)
    26. {
    27. QStringList rowData;
    28. for (int col = 0; col < tableWidget->columnCount(); col++)
    29. {
    30. QTableWidgetItem *item = tableWidget->item(row, col);
    31. if (item)
    32. {
    33. rowData << item->text();
    34. }
    35. else
    36. {
    37. rowData << "";
    38. }
    39. }
    40. stream << rowData.join(",") << "\n";
    41. }
    42. file.close();
    43. }
    44. else
    45. {
    46. // 打开文件失败,可以在此处理错误
    47. }
    48. }
    49. void GeneralPolicyWidget::importCSVToTableWidget(const QString &filePath, QTableWidget *tableWidget)
    50. {
    51. QFile file(filePath);
    52. if (file.open(QIODevice::ReadOnly | QIODevice::Text))
    53. {
    54. QTextStream stream(&file);
    55. int rowCount = 0; // 用于计算行数
    56. // 读取CSV文件的每一行
    57. while (!stream.atEnd())
    58. {
    59. QString line = stream.readLine();
    60. QStringList fields = line.split(","); // 使用逗号分隔字段
    61. // 跳过空行
    62. if (fields.isEmpty()) {
    63. continue;
    64. }
    65. // 创建新行并填充数据
    66. if (rowCount == 0) // 第一行作为表头
    67. {
    68. tableWidget->setColumnCount(fields.count());
    69. tableWidget->setHorizontalHeaderLabels(fields);
    70. }
    71. else // 其他行作为数据
    72. {
    73. int row = tableWidget->rowCount();
    74. tableWidget->insertRow(row);
    75. for (int col = 0; col < fields.count(); col++)
    76. {
    77. QTableWidgetItem *item = new QTableWidgetItem(fields[col]);
    78. tableWidget->setItem(row, col, item);
    79. }
    80. }
    81. rowCount++;
    82. }
    83. file.close();
    84. }
    85. else
    86. {
    87. // 打开文件失败,可以在此处理错误
    88. }
    89. }

    UDP线程

    1. #include
    2. #include
    3. #include
    4. class UdpReceiver : public QObject
    5. {
    6. Q_OBJECT
    7. public slots:
    8. void processPendingDatagrams()
    9. {
    10. while (udpSocket.hasPendingDatagrams())
    11. {
    12. QByteArray datagram;
    13. datagram.resize(udpSocket.pendingDatagramSize());
    14. QHostAddress sender;
    15. quint16 senderPort;
    16. udpSocket.readDatagram(datagram.data(), datagram.size(), &sender, &senderPort);
    17. // 根据接收到的消息内容执行不同的功能
    18. if (datagram == "Message1")
    19. {
    20. // 执行功能1
    21. }
    22. else if (datagram == "Message2")
    23. {
    24. // 执行功能2
    25. }
    26. // 添加更多的消息处理逻辑
    27. qDebug() << "Received datagram:" << datagram;
    28. }
    29. }
    30. private:
    31. QUdpSocket udpSocket;
    32. };
    33. int main(int argc, char *argv[])
    34. {
    35. QCoreApplication a(argc, argv);
    36. UdpReceiver udpReceiver;
    37. // 创建UDP套接字并绑定到指定端口
    38. if (!udpReceiver.udpSocket.bind(QHostAddress::Any, 12345))
    39. {
    40. qDebug() << "Failed to bind UDP socket!";
    41. return 1;
    42. }
    43. // 连接信号和槽
    44. QObject::connect(&udpReceiver.udpSocket, SIGNAL(readyRead()), &udpReceiver, SLOT(processPendingDatagrams()));
    45. // 创建并启动独立线程
    46. QThread udpThread;
    47. udpReceiver.moveToThread(&udpThread);
    48. udpThread.start();
    49. return a.exec();
    50. }

    数据库增删改操作

    1. class DataRecord {
    2. public:
    3. DataRecord(const QString &name = QString(),
    4. const QString &dizhi = QString(),
    5. const QString &dongzuo = QString(),
    6. const QString &fengzhuang = QString(),
    7. const QString &suanfa = QString())
    8. : name(name), dizhi(dizhi), dongzuo(dongzuo), fengzhuang(fengzhuang), suanfa(suanfa) {}
    9. QString name;
    10. QString dizhi;
    11. QString dongzuo;
    12. QString fengzhuang;
    13. QString suanfa;
    14. };
    15. #include
    16. #include
    17. #include
    18. #include
    19. #include
    20. #include
    21. #include
    22. #include
    23. #include
    24. #include
    25. #include
    26. #include
    27. #include
    28. static QSqlDatabase db_strategy;
    29. bool MulticastPolicyWidget::connectToDatabase()
    30. {
    31. // 初始化数据库连接
    32. db_strategy = QSqlDatabase::addDatabase("QSQLITE");
    33. db_strategy.setDatabaseName("strategy.db"); // 数据库文件的名称,替换为你想要的名称
    34. // 打开数据库连接
    35. if (!db_strategy.open()) {
    36. qDebug() << "Failed to open database:" << db_strategy.lastError().text();
    37. return 1;
    38. }
    39. // 创建表格并执行 SQL 语句来初始化数据库
    40. QSqlQuery query;
    41. query.exec("CREATE TABLE IF NOT EXISTS zuboguanli ("
    42. "name text primary key,"
    43. "dizhi TEXT,"
    44. "dongzuo TEXT,"
    45. "fengzhuang TEXT,"
    46. "suanfa TEXT"
    47. ")");
    48. // 检查 SQL 查询是否执行成功
    49. if (query.lastError().isValid()) {
    50. qDebug() << "Database query error:" << query.lastError().text();
    51. return 1;
    52. }
    53. // 关闭数据库连接(如果需要的话)
    54. // db_strategy.close();
    55. }
    56. // 增加数据
    57. bool MulticastPolicyWidget::addDataToDatabase(const DataRecord &record) {
    58. QSqlQuery query(db_strategy);
    59. query.prepare("INSERT INTO zuboguanli (name, dizhi,dongzuo,fengzhuang,suanfa) VALUES (?, ?, ?, ?, ?)");
    60. query.bindValue(0, record.name);
    61. query.bindValue(1, record.dizhi);
    62. query.bindValue(2, record.dongzuo);
    63. query.bindValue(3, record.fengzhuang);
    64. query.bindValue(4, record.suanfa);
    65. if (query.exec()) {
    66. qDebug() << "成功插入数据";
    67. return true;
    68. } else {
    69. qDebug() << "插入数据失败:" << query.lastError().text();
    70. return false;
    71. }
    72. }
    73. // 删除数据
    74. bool MulticastPolicyWidget::deleteDataFromDatabase(const QString &name) {
    75. QSqlQuery query(db_strategy);
    76. query.prepare("DELETE FROM zuboguanli WHERE name = ?");
    77. query.bindValue(0, name);
    78. if (query.exec()) {
    79. qDebug() << "成功删除数据";
    80. return true;
    81. } else {
    82. qDebug() << "删除数据失败:" << query.lastError().text();
    83. return false;
    84. }
    85. }
    86. // 修改数据
    87. bool MulticastPolicyWidget::updateDataInDatabase(const DataRecord &record) {
    88. QSqlQuery query(db_strategy);
    89. query.prepare("UPDATE zuboguanli SET dizhi = ?, dongzuo = ?, fengzhuang = ?, suanfa = ? WHERE name = ?");
    90. query.bindValue(0, record.dizhi);
    91. query.bindValue(1, record.dongzuo);
    92. query.bindValue(2, record.fengzhuang);
    93. query.bindValue(3, record.suanfa);
    94. query.bindValue(4, record.name);
    95. if (query.exec()) {
    96. qDebug() << "成功更新数据";
    97. return true;
    98. } else {
    99. qDebug() << "更新数据失败:" << query.lastError().text();
    100. return false;
    101. }
    102. }
    103. //数据库打印到表
    104. void MulticastPolicyWidget::printTableDataToTableWidget(const QString &tableName, QTableWidget *tableWidget) {
    105. // 清空表格中的数据
    106. tableWidget->setRowCount(0);
    107. // 执行查询获取指定表的所有数据
    108. QSqlQuery query;
    109. query.exec(QString("SELECT * FROM %1").arg(tableName));
    110. // 设置表格的列数
    111. if (query.isActive()) {
    112. int columnCount = query.record().count();
    113. tableWidget->setColumnCount(columnCount);
    114. // 逐行填充数据
    115. int rowCount = 0;
    116. while (query.next()) {
    117. tableWidget->insertRow(rowCount);
    118. for (int col = 0; col < columnCount; col++) {
    119. tableWidget->setItem(rowCount, col, new QTableWidgetItem(query.value(col).toString()));
    120. }
    121. rowCount++;
    122. }
    123. } else {
    124. // 查询失败,可以在此处理错误
    125. }
    126. }
    127. //数据库转json
    128. QJsonDocument MulticastPolicyWidget::tableDataToJson(const QString &tableName) {
    129. // 创建一个 JSON 数组来存储表中的数据
    130. QJsonArray jsonArray;
    131. // 执行查询获取指定表的所有数据
    132. QSqlQuery query;
    133. query.exec(QString("SELECT * FROM %1").arg(tableName));
    134. // 将查询结果转换为 JSON 数组
    135. if (query.isActive()) {
    136. int columnCount = query.record().count();
    137. while (query.next()) {
    138. QJsonObject jsonObject;
    139. for (int col = 0; col < columnCount; col++) {
    140. QString columnName = query.record().fieldName(col);
    141. QVariant columnValue = query.value(col);
    142. jsonObject[columnName] = QJsonValue::fromVariant(columnValue);
    143. }
    144. jsonArray.append(jsonObject);
    145. }
    146. } else {
    147. // 查询失败,可以在此处理错误
    148. }
    149. // 创建一个 JSON 文档并返回
    150. QJsonDocument jsonDocument(jsonArray);
    151. return jsonDocument;
    152. }
    153. //获取界面文本
    154. DataRecord MulticastPolicyWidget::createDataRecordFromUI() {
    155. QString name = ui->lineEdit->text();
    156. QString dizhi = ui->lineEdit_2->text();
    157. QString dongzuo = ui->comboBox->currentText();
    158. QString fengzhuang = ui->comboBox_2->currentText();
    159. QString suanfa = ui->comboBox_3->currentText();
    160. DataRecord record(name, dizhi, dongzuo, fengzhuang, suanfa);
    161. return record;
    162. }

    输入弹窗

    1. #include
    2. DataRecord MulticastPolicyWidget::createDataRecordFromUIid() {
    3. // 使用QInputDialog获取用户输入的ID
    4. bool ok;
    5. QString id = QInputDialog::getText(this, "输入ID", "请输入ID:", QLineEdit::Normal, QString(), &ok);
    6. if (ok) {
    7. // 用户点击了"确定"按钮
    8. DataRecord record(id);
    9. return record;
    10. } else {
    11. // 用户点击了"取消"按钮或关闭了输入对话框
    12. // 返回一个空的DataRecord或者根据需要进行处理
    13. return DataRecord();
    14. }
    15. }

    我的

    1. #include "multicastpolicywidget.h"
    2. #include "ui_multicastpolicywidget.h"
    3. #include
    4. #include
    5. #include
    6. #include
    7. #include
    8. #include
    9. #include
    10. #include
    11. #include
    12. #include
    13. #include
    14. #include
    15. #include
    16. #include "QInputDialog"
    17. #include "QVBoxLayout"
    18. static QSqlDatabase db_strategy;
    19. MulticastPolicyWidget::MulticastPolicyWidget(QWidget *parent) :
    20. QWidget(parent),
    21. ui(new Ui::MulticastPolicyWidget)
    22. {
    23. ui->setupUi(this);
    24. //动作
    25. ui->comboBox->addItem("加密");
    26. ui->comboBox->addItem("透传");
    27. ui->comboBox->addItem("丢弃");
    28. //封装模式
    29. ui->comboBox_2->addItem("线速(传输模式)");
    30. ui->comboBox_2->addItem("线速(隧道模式)");
    31. ui->comboBox_2->addItem("统型模式");
    32. //算法选择
    33. ui->comboBox_3->addItem("专核");
    34. ui->comboBox_3->addItem("普密");
    35. connectToDatabase();
    36. ui->tableWidget->verticalHeader()->setVisible(false);
    37. //ui->tableWidget->setShowGrid(false); // 默认情况下就是显示网格
    38. ui->tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
    39. ui->tableWidget->setColumnCount(5);
    40. ui->tableWidget_2->verticalHeader()->setVisible(false);
    41. //ui->tableWidget->setShowGrid(false); // 默认情况下就是显示网格
    42. ui->tableWidget_2->setEditTriggers(QAbstractItemView::NoEditTriggers);
    43. ui->tableWidget_2->verticalHeader()->setVisible(false); // 隐藏垂直表头
    44. ui->tableWidget_2->horizontalHeader()->setVisible(false); //
    45. ui->tableWidget_2->setRowCount(0);
    46. ui->tableWidget_2->setColumnCount(1);
    47. connect(ui->tableWidget, &QTableWidget::itemSelectionChanged, this, &MulticastPolicyWidget::jiemian);
    48. }
    49. MulticastPolicyWidget::~MulticastPolicyWidget()
    50. {
    51. delete ui;
    52. db_strategy.close();
    53. }
    54. //添加ID
    55. void MulticastPolicyWidget::on_pushButton_clicked()
    56. {
    57. bool ok;
    58. QString newText = QInputDialog::getText(this, "添加行", "输入新文本:", QLineEdit::Normal, NULL, &ok);
    59. QTableWidgetItem *item=new QTableWidgetItem(newText);
    60. if (ok) {
    61. int row = ui->tableWidget_2->rowCount();
    62. ui->tableWidget_2->insertRow(row);
    63. ui->tableWidget_2->setItem(row,0,item);
    64. }
    65. }
    66. //编辑ID
    67. void MulticastPolicyWidget::on_pushButton_2_clicked()
    68. {
    69. int currentRow = ui->tableWidget_2->currentRow();
    70. if (currentRow >= 0) {
    71. // 获取当前行的文本
    72. QString currentText = ui->tableWidget_2->item(currentRow, 0)->text();
    73. // 弹出输入对话框
    74. bool ok;
    75. QString newText = QInputDialog::getText(this, "修改行", "输入新文本:", QLineEdit::Normal, currentText, &ok);
    76. // 如果用户点击了 OK 按钮,则更新表格中的文本
    77. if (ok) {
    78. ui->tableWidget_2->item(currentRow, 0)->setText(newText);
    79. }
    80. }
    81. }
    82. //删除ID
    83. void MulticastPolicyWidget::on_pushButton_3_clicked()
    84. {
    85. int currentRow = ui->tableWidget_2->currentRow();
    86. if (currentRow >= 0) {
    87. ui->tableWidget_2->removeRow(currentRow);
    88. }
    89. }
    90. //添加策略
    91. void MulticastPolicyWidget::on_pushButton_4_clicked()
    92. {
    93. addDataToDatabase(createDataRecordFromUI());
    94. QVector<int> columnsToPrint;
    95. columnsToPrint << 0 << 1<<2<<3<<4;
    96. printTableDataToTableWidget("zuboguanli", ui->tableWidget, columnsToPrint);
    97. }
    98. //修改策略
    99. void MulticastPolicyWidget::on_pushButton_5_clicked()
    100. {
    101. updateDataInDatabase(createDataRecordFromUI());
    102. QVector<int> columnsToPrint;
    103. columnsToPrint << 0 << 1<<2<<3<<4; // 这里假设第1列和第3列需要打印
    104. printTableDataToTableWidget("zuboguanli", ui->tableWidget, columnsToPrint);
    105. }
    106. //删除策略
    107. void MulticastPolicyWidget::on_pushButton_6_clicked()
    108. {
    109. DataRecord rec=createDataRecordFromUI();
    110. deleteDataFromDatabase(rec.name);
    111. QVector<int> columnsToPrint;
    112. columnsToPrint << 0 << 1<<2<<3<<4; // 这里假设第1列和第3列需要打印
    113. printTableDataToTableWidget("zuboguanli", ui->tableWidget, columnsToPrint);
    114. }
    115. //数据库操作
    116. bool MulticastPolicyWidget::connectToDatabase()
    117. {
    118. // 初始化数据库连接
    119. db_strategy = QSqlDatabase::addDatabase("QSQLITE");
    120. db_strategy.setDatabaseName("strategy.db"); // 数据库文件的名称,替换为你想要的名称
    121. // 打开数据库连接
    122. if (!db_strategy.open()) {
    123. qDebug() << "Failed to open database:" << db_strategy.lastError().text();
    124. return 1;
    125. }
    126. deleteTableFromDatabase("zuboguanli");
    127. addTableToDatabase();
    128. // 创建表格并执行 SQL 语句来初始化数据库
    129. // 关闭数据库连接(如果需要的话)
    130. // db_strategy.close();
    131. }
    132. bool MulticastPolicyWidget::addTableToDatabase()
    133. {
    134. QSqlQuery query;
    135. query.exec("CREATE TABLE IF NOT EXISTS zuboguanli ("
    136. "name text primary key,"
    137. "dizhi TEXT,"
    138. "dongzuo TEXT,"
    139. "fengzhuang TEXT,"
    140. "suanfa TEXT,"
    141. "mudiid TEXT"
    142. ")");
    143. // 检查 SQL 查询是否执行成功
    144. if (query.lastError().isValid()) {
    145. qDebug() << "Database query error:" << query.lastError().text();
    146. return 1;
    147. }
    148. }
    149. //删除表
    150. bool MulticastPolicyWidget::deleteTableFromDatabase(const QString &tableName) {
    151. QSqlQuery query(db_strategy);
    152. QString deleteQuery = QString("DROP TABLE IF EXISTS %1").arg(tableName);
    153. if (query.exec(deleteQuery)) {
    154. qDebug() << "成功删除表:" << tableName;
    155. return true;
    156. } else {
    157. qDebug() << "删除表失败:" << query.lastError().text();
    158. return false;
    159. }
    160. }
    161. // 增加数据
    162. bool MulticastPolicyWidget::addDataToDatabase(const DataRecord &record) {
    163. QSqlQuery query(db_strategy);
    164. query.prepare("INSERT INTO zuboguanli (name, dizhi,dongzuo,fengzhuang,suanfa,mudiid) VALUES (?, ?, ?, ?, ?,?)");
    165. query.bindValue(0, record.name);
    166. query.bindValue(1, record.dizhi);
    167. query.bindValue(2, record.dongzuo);
    168. query.bindValue(3, record.fengzhuang);
    169. query.bindValue(4, record.suanfa);
    170. query.bindValue(5, record.mudiid);
    171. printDataRecord(record);
    172. if (query.exec()) {
    173. qDebug() << "成功插入数据";
    174. return true;
    175. } else {
    176. qDebug() << "插入数据失败:" << query.lastError().text();
    177. return false;
    178. }
    179. }
    180. // 删除数据
    181. bool MulticastPolicyWidget::deleteDataFromDatabase(const QString &name) {
    182. QSqlQuery query(db_strategy);
    183. query.prepare("DELETE FROM zuboguanli WHERE name = ?");
    184. query.bindValue(0, name);
    185. if (query.exec()) {
    186. qDebug() << "成功删除数据";
    187. return true;
    188. } else {
    189. qDebug() << "删除数据失败:" << query.lastError().text();
    190. return false;
    191. }
    192. }
    193. // 修改数据
    194. bool MulticastPolicyWidget::updateDataInDatabase(const DataRecord &record) {
    195. QSqlQuery query(db_strategy);
    196. query.prepare("UPDATE zuboguanli SET dizhi = ?, dongzuo = ?, fengzhuang = ?, suanfa = ?,mudiid=? WHERE name = ?");
    197. query.bindValue(0, record.dizhi);
    198. query.bindValue(1, record.dongzuo);
    199. query.bindValue(2, record.fengzhuang);
    200. query.bindValue(3, record.suanfa);
    201. query.bindValue(4, record.mudiid);
    202. query.bindValue(5, record.name);
    203. if (query.exec()) {
    204. qDebug() << "成功更新数据";
    205. return true;
    206. } else {
    207. qDebug() << "更新数据失败:" << query.lastError().text();
    208. return false;
    209. }
    210. }
    211. //点击查询数据
    212. DataRecord MulticastPolicyWidget::getDataRecordFromSelectedRow() {
    213. DataRecord record;
    214. // 获取选中的行号
    215. int selectedRow = ui->tableWidget->currentRow();
    216. // 检查是否有行被选中
    217. if (selectedRow < 0) {
    218. qDebug()<<"无选中行";
    219. return record;
    220. }
    221. // 提取选中行的标识数据,例如 name
    222. QString name = ui->tableWidget->item(selectedRow, 0)->text(); // 假设该列是 name
    223. // 执行数据库查询
    224. QSqlQuery query(db_strategy);
    225. query.prepare("SELECT * FROM zuboguanli WHERE name = ?");
    226. query.bindValue(0, name);
    227. if (query.exec() && query.first()) {
    228. // 从查询结果中提取数据并填充到 DataRecord 对象
    229. record.name = query.value("name").toString();
    230. record.dizhi = query.value("dizhi").toString();
    231. record.dongzuo = query.value("dongzuo").toString();
    232. record.fengzhuang = query.value("fengzhuang").toString();
    233. record.suanfa = query.value("suanfa").toString();
    234. record.mudiid = query.value("mudiid").toString();
    235. } else {
    236. qDebug() << "从数据库查询数据失败:" << query.lastError().text();
    237. }
    238. return record;
    239. }
    240. //数据库打印到表
    241. void MulticastPolicyWidget::printTableDataToTableWidget(const QString &tableName, QTableWidget *tableWidget, const QVector<int> &columnsToPrint) {
    242. // 清空表格中的数据
    243. tableWidget->setRowCount(0);
    244. // 执行查询获取指定表的所有数据
    245. QSqlQuery query;
    246. query.exec(QString("SELECT * FROM %1").arg(tableName));
    247. // 设置表格的列数
    248. if (query.isActive()) {
    249. int tableWidgetColumnCount = columnsToPrint.size();
    250. // 设置表格的列数(与入参中的列数相对应)
    251. tableWidget->setColumnCount(tableWidgetColumnCount);
    252. // 逐行填充数据
    253. int rowCount = 0;
    254. while (query.next()) {
    255. tableWidget->insertRow(rowCount);
    256. for (int i = 0; i < tableWidgetColumnCount; i++) {
    257. int col = columnsToPrint[i];
    258. tableWidget->setItem(rowCount, i, new QTableWidgetItem(query.value(col).toString()));
    259. }
    260. rowCount++;
    261. }
    262. } else {
    263. // 查询失败,可以在此处理错误
    264. }
    265. }
    266. //数据库转json
    267. QJsonDocument MulticastPolicyWidget::tableDataToJson(const QString &tableName) {
    268. // 创建一个 JSON 数组来存储表中的数据
    269. QJsonArray jsonArray;
    270. // 执行查询获取指定表的所有数据
    271. QSqlQuery query;
    272. query.exec(QString("SELECT * FROM %1").arg(tableName));
    273. // 将查询结果转换为 JSON 数组
    274. if (query.isActive()) {
    275. int columnCount = query.record().count();
    276. while (query.next()) {
    277. QJsonObject jsonObject;
    278. for (int col = 0; col < columnCount; col++) {
    279. QString columnName = query.record().fieldName(col);
    280. QVariant columnValue = query.value(col);
    281. jsonObject[columnName] = QJsonValue::fromVariant(columnValue);
    282. }
    283. jsonArray.append(jsonObject);
    284. }
    285. } else {
    286. // 查询失败,可以在此处理错误
    287. }
    288. // 创建一个 JSON 文档并返回
    289. QJsonDocument jsonDocument(jsonArray);
    290. return jsonDocument;
    291. }
    292. //json转数据库
    293. //获取界面文本
    294. DataRecord MulticastPolicyWidget::createDataRecordFromUI() {
    295. QString name = ui->lineEdit->text();
    296. QString dizhi = ui->lineEdit_2->text();
    297. if (name.isEmpty() || dizhi.isEmpty()) {
    298. // 如果 name 或 dizhi 为空,弹出警告
    299. QMessageBox::warning(this, "警告", "名称和地址不能为空!");
    300. } else if (name.length() > 15) {
    301. // 如果 name 长度超过15个字符,弹出警告
    302. QMessageBox::warning(this, "警告", "名称长度不能超过15个字符!");
    303. } else {
    304. // 检查 dizhi 格式是否合法
    305. QRegExp ipRegExp("(25[0-5]|2[0-4][0-9]|[0-1]?[0-9][0-9]?)\\."
    306. "(25[0-5]|2[0-4][0-9]|[0-1]?[0-9][0-9]?)\\."
    307. "(25[0-5]|2[0-4][0-9]|[0-1]?[0-9][0-9]?)\\."
    308. "(25[0-5]|2[0-4][0-9]|[0-1]?[0-9][0-9]?)");
    309. if (!ipRegExp.exactMatch(dizhi)) {
    310. // 如果 dizhi 不匹配 IP 地址格式,弹出警告
    311. QMessageBox::warning(this, "警告", "地址格式不合法,请输入有效的 IP 地址!");
    312. } else {
    313. // 执行其他操作,因为输入是有效的
    314. }
    315. }
    316. QString dongzuo = ui->comboBox->currentText();
    317. QString fengzhuang = ui->comboBox_2->currentText();
    318. QString suanfa = ui->comboBox_3->currentText();
    319. QString mudiid=tableWidgetToText(ui->tableWidget_2) ;
    320. DataRecord record(name, dizhi, dongzuo, fengzhuang, suanfa,mudiid);
    321. return record;
    322. }
    323. //设置界面文本
    324. void MulticastPolicyWidget::setDataRecordToUI(const DataRecord &record) {
    325. ui->lineEdit->setText(record.name);
    326. ui->lineEdit_2->setText(record.dizhi);
    327. ui->comboBox->setCurrentText(record.dongzuo);
    328. ui->comboBox_2->setCurrentText(record.fengzhuang);
    329. ui->comboBox_3->setCurrentText(record.suanfa);
    330. textToTableWidget(record.mudiid,ui->tableWidget_2);
    331. }
    332. //表格转文本
    333. QString MulticastPolicyWidget::tableWidgetToText(QTableWidget *tableWidget) {
    334. QString text;
    335. // 遍历每一行
    336. for (int row = 0; row < tableWidget->rowCount(); row++) {
    337. // 遍历每一列
    338. for (int col = 0; col < tableWidget->columnCount(); col++) {
    339. // 获取单元格的文本
    340. QTableWidgetItem *item = tableWidget->item(row, col);
    341. if (item) {
    342. text += item->text();
    343. }
    344. // 添加列之间的分隔符,例如制表符或逗号
    345. text += "\t"; // 在这里使用制表符分隔
    346. }
    347. // 添加行之间的分隔符,例如换行符
    348. text += "\n";
    349. }
    350. return text;
    351. }
    352. //文本转表格
    353. void MulticastPolicyWidget::textToTableWidget(const QString &text, QTableWidget *tableWidget) {
    354. // 清空表格
    355. tableWidget->clear();
    356. tableWidget->setRowCount(0);
    357. tableWidget->setColumnCount(0);
    358. QStringList lines = text.split('\n');
    359. int rowCount = lines.size();
    360. // 遍历每一行
    361. for (int row = 0; row < rowCount; row++) {
    362. // 移除行首和行尾的空白字符
    363. QString line = lines[row].trimmed();
    364. if (line.isEmpty()) {
    365. continue; // 如果行为空,跳过
    366. }
    367. // 分割每一行以获取列数据
    368. QStringList columns = line.split('\t'); // 使用制表符分隔
    369. // 如果列数与表格列数不匹配,添加新列
    370. if (tableWidget->columnCount() < columns.size()) {
    371. tableWidget->setColumnCount(columns.size());
    372. }
    373. // 添加新行
    374. tableWidget->insertRow(row);
    375. // 填充单元格数据
    376. for (int col = 0; col < columns.size(); col++) {
    377. QTableWidgetItem *item = new QTableWidgetItem(columns[col]);
    378. tableWidget->setItem(row, col, item);
    379. }
    380. }
    381. }
    382. void MulticastPolicyWidget::jiemian()
    383. {
    384. DataRecord rec=getDataRecordFromSelectedRow();
    385. setDataRecordToUI(rec);
    386. printDataRecord(rec);
    387. }
    388. void MulticastPolicyWidget::printDataRecord(const DataRecord &record) {
    389. qDebug() << "Name: " << record.name;
    390. qDebug() << "Dizhi: " << record.dizhi;
    391. qDebug() << "Dongzuo: " << record.dongzuo;
    392. qDebug() << "Fengzhuang: " << record.fengzhuang;
    393. qDebug() << "Suanfa: " << record.suanfa;
    394. qDebug() << "Mudiid: " << record.mudiid;
    395. }
    1. #ifndef MULTICASTPOLICYWIDGET_H
    2. #define MULTICASTPOLICYWIDGET_H
    3. #include
    4. #include
    5. namespace Ui {
    6. class MulticastPolicyWidget;
    7. }
    8. class DataRecord {
    9. public:
    10. DataRecord(const QString &name = QString(),
    11. const QString &dizhi = QString(),
    12. const QString &dongzuo = QString(),
    13. const QString &fengzhuang = QString(),
    14. const QString &suanfa = QString(),
    15. const QString &mudiid = QString())
    16. : name(name), dizhi(dizhi), dongzuo(dongzuo), fengzhuang(fengzhuang), suanfa(suanfa),mudiid(mudiid) {}
    17. QString name;
    18. QString dizhi;
    19. QString dongzuo;
    20. QString fengzhuang;
    21. QString suanfa;
    22. QString mudiid;
    23. };
    24. class MulticastPolicyWidget : public QWidget
    25. {
    26. Q_OBJECT
    27. public:
    28. explicit MulticastPolicyWidget(QWidget *parent = nullptr);
    29. ~MulticastPolicyWidget();
    30. bool connectToDatabase();
    31. bool addDataToDatabase(const DataRecord &record);
    32. bool deleteDataFromDatabase(const QString &name);
    33. bool updateDataInDatabase(const DataRecord &record);
    34. void printTableDataToTableWidget(const QString &tableName, QTableWidget *tableWidget, const QVector<int> &columnsToPrint);
    35. QJsonDocument tableDataToJson(const QString &tableName);
    36. DataRecord createDataRecordFromUI();
    37. QString tableWidgetToText(QTableWidget *tableWidget);
    38. void textToTableWidget(const QString &text, QTableWidget *tableWidget);
    39. void setDataRecordToUI(const DataRecord &record);
    40. DataRecord getDataRecordFromSelectedRow();
    41. void jiemian();
    42. bool deleteTableFromDatabase(const QString &tableName);
    43. void printDataRecord(const DataRecord &record);
    44. bool addTableToDatabase();
    45. private slots:
    46. void on_pushButton_clicked();
    47. void on_pushButton_2_clicked();
    48. void on_pushButton_3_clicked();
    49. void on_pushButton_4_clicked();
    50. void on_pushButton_5_clicked();
    51. void on_pushButton_6_clicked();
    52. private:
    53. Ui::MulticastPolicyWidget *ui;
    54. };
    55. #endif // MULTICASTPOLICYWIDGET_H

    进度条平滑效果

    1. 要实现平滑地将 `QProgressBar` 滑块拉到最大值,你可以使用 `QPropertyAnimation` 类。这将允许你在一段时间内逐渐增加 `QProgressBar` 的值,从而实现平滑的效果。下面是如何使用 `QPropertyAnimation` 来实现这一点:
    2. 首先,确保你在 `.pro` 文件中添加了 `widgets` 模块:
    3. ```qmake
    4. QT += widgets
    5. ```
    6. 然后,使用以下代码实现平滑的效果:
    7. ```cpp
    8. // 创建 QPropertyAnimation 对象
    9. QPropertyAnimation *animation = new QPropertyAnimation(ui->progressBar, "value");
    10. // 设置动画参数
    11. animation->setDuration(2000); // 2秒
    12. animation->setStartValue(ui->progressBar->value());
    13. animation->setEndValue(ui->progressBar->maximum());
    14. // 开始动画
    15. animation->start();
    16. ```
    17. 这段代码将创建一个 `QPropertyAnimation` 对象,将 `value` 属性从当前值逐渐增加到最大值,这样你就可以实现平滑的进度条动画效果。

    信号与槽

    1. connect(m_syswidget,SIGNAL(Applicationquit()),this,SLOT(Exit()));
    2. connect(m_syswidget,&SystemManageWidget::Applicationquit,qApp,&QApplication::quit);

    时间添加1s

    dateTime = dateTime.addSecs(1); // 添加一秒

    设计方法

    1. 如果你希望简化使用的通用函数,可以创建一个模板函数,它可以接受任何类型的数据,如下所示:
    2. ```cpp
    3. #include
    4. #include
    5. template <typename T>
    6. void handleResult(const QJsonObject &recv, const T &key, std::function<void()> onSuccess, std::function<void()> onFailure) {
    7. if (recv.contains(key)) {
    8. if (recv[key].toBool()) {
    9. onSuccess(); // 调用成功操作函数
    10. } else {
    11. onFailure(); // 调用失败操作函数
    12. }
    13. }
    14. }
    15. // 使用示例
    16. handleResult(recv1, "SetTime",
    17. []() {
    18. // 操作函数1
    19. },
    20. []() {
    21. // 操作函数2
    22. }
    23. );
    24. handleResult(recv1, "AnotherKey",
    25. []() {
    26. // 操作函数3
    27. },
    28. []() {
    29. // 操作函数4
    30. }
    31. );
    32. ```
    33. 这个通用函数现在可以接受一个键(key)和你希望检查的 QJsonObject,以及两个操作函数。这样,你可以根据需要简单地调用通用函数来处理不同的 JSON 数据和操作函数。

    更好的设计方法

    1. 如果你希望 `handleResult` 函数支持具有不同参数的 `onSuccess` 和 `onFailure` 函数,可以使用 C++ 的模板来实现。以下是修改后的函数:
    2. ```cpp
    3. template <typename T, typename FuncSuccess, typename FuncFailure>
    4. void SystemManageWidget::handleResult(const QJsonObject &recv, const T &key, FuncSuccess onSuccess, FuncFailure onFailure) {
    5. if (recv.contains(key)) {
    6. if (recv[key].toBool()) {
    7. onSuccess(); // 调用成功操作函数
    8. } else {
    9. onFailure(); // 调用失败操作函数
    10. }
    11. }
    12. }
    13. ```
    14. 在这个版本中, `handleResult` 接受两个函数对象 `onSuccess` 和 `onFailure`,它们可以带有任意数量的参数。你可以像这样使用它:
    15. ```cpp
    16. handleResult(recv, "SetTime", [this]() {
    17. // 成功操作函数,可以带有任意参数
    18. showMessage("操作成功", "设置时间操作成功!");
    19. }, [this]() {
    20. // 失败操作函数,可以带有任意参数
    21. showMessage("操作成功", "设置时间操作失败!");
    22. });
    23. ```
    24. 在 lambda 函数中没有捕获 this 指针,无法使用类的成员函数
    25. 通过这种方式,你可以根据具体需要定义成功和失败操作函数,并将它们传递给 `handleResult`,而不受参数数量的限制。

    请设计一个函数事界面失能,并记时三秒,若三秒后仍然失能,则使界面使能

    1. 你可以使用 Qt 的 `QTimer` 类来实现这个功能。以下是一个设计函数的示例,该函数将界面禁用,然后在三秒后重新启用:
    2. ```cpp
    3. #include
    4. // 在你的类中定义一个 QTimer 成员变量
    5. QTimer *disableTimer;
    6. // 在你的构造函数中初始化 QTimer
    7. YourConstructor::YourConstructor() {
    8. disableTimer = new QTimer(this);
    9. disableTimer->setSingleShot(true);
    10. connect(disableTimer, &QTimer::timeout, this, &YourClass::enableUI); // 在超时后启用界面
    11. }
    12. // 编写一个函数来禁用界面并启动计时器
    13. void YourClass::disableUI() {
    14. // 禁用你的界面元素,例如:ui->pushButton->setEnabled(false);
    15. // 启动计时器,三秒后触发 timeout 信号
    16. this->setEnabled(false);
    17. disableTimer->start(3000); // 3000 毫秒(3秒)
    18. }
    19. // 编写一个函数在计时器超时后启用界面
    20. void YourClass::enableUI() {
    21. if(!this->isEnabled())
    22. {
    23. ///
    24. }
    25. // 启用你的界面元素,例如:ui->pushButton->setEnabled(true);
    26. this->setEnabled(true);
    27. }
    28. ```
    29. 上述代码首先初始化了一个单次触发的 `QTimer`,并连接了 `timeout` 信号到 `enableUI` 槽函数。`disableUI` 函数在需要禁用界面时调用,它会禁用界面元素,然后启动计时器。当计时器超时后(三秒后),`timeout` 信号触发,执行 `enableUI` 槽函数,这时可以重新启用界面元素。
    30. 请注意,你需要适应代码以符合你的具体界面和需求。

    上一个问题更简洁的方法

    1. 你可以简化你的代码,如下所示:
    2. ```cpp
    3. disableTimer = new QTimer(this);
    4. disableTimer->setSingleShot(true);
    5. connect(disableTimer, &QTimer::timeout, this, &SystemManageWidget::enableUI); // 在超时后启用界面
    6. void SystemManageWidget::disableUI()
    7. {
    8. setEnabled(false);
    9. disableTimer->start(5000); // 5000 毫秒(5秒)
    10. }
    11. void SystemManageWidget::enableUI()
    12. {
    13. if (!isEnabled())
    14. showMessage("请求超时");
    15. setEnabled(true);
    16. }
    17. ```
    18. 这个简化的代码与之前的代码功能相同,但通过删除冗余的`this->`和将`setEnabled`直接应用于对象,使代码更加简洁。

    通用弹窗

    1. 你可以创建一个通用的函数来简化这个弹出窗口的创建和处理。以下是一个示例函数,用于创建通用的消息框:
    2. ```cpp
    3. #include
    4. #include
    5. int showCustomMessageBox(const QString &title, const QString &text,
    6. const QString &confirmButtonText, const QString &cancelButtonText,
    7. QMessageBox::Icon icon = QMessageBox::Information, QWidget *parent = nullptr)
    8. {
    9. QMessageBox messageBox(icon, title, text, QMessageBox::Ok | QMessageBox::Cancel, parent);
    10. messageBox.setButtonText(QMessageBox::Ok, confirmButtonText);
    11. messageBox.setButtonText(QMessageBox::Cancel, cancelButtonText);
    12. int choice = messageBox.exec();
    13. return choice;
    14. }
    15. ```
    16. 你可以将这个函数添加到你的代码中,然后在需要显示消息框的地方调用它。例如:
    17. ```cpp
    18. int choice = showCustomMessageBox("密码机管理器", "恢复设置成功,是否退出管理器", "确认", "取消", QMessageBox::Warning);
    19. if (choice == QMessageBox::Ok)
    20. {
    21. // 用户点击确认按钮的处理逻辑
    22. emit a();
    23. }
    24. else if (choice == QMessageBox::Cancel)
    25. {
    26. // 用户点击取消按钮的处理逻辑
    27. emit b();
    28. }
    29. ```
    30. 这个函数接受标题、文本、确认按钮文本、取消按钮文本和图标作为参数,并返回用户的选择,使你可以更容易地创建和处理通用的消息框。

    设计方法使用问题

    1. template <typename T, typename FuncSuccess, typename FuncFailure>
    2. void SystemManageWidget::handleResult(const QJsonObject &recv, const T &key, FuncSuccess onSuccess, FuncFailure onFailure) {
    3. this->setEnabled(true);
    4. if (recv.contains(key)) {
    5. if (recv[key].toBool()) {
    6. onSuccess(); // 调用成功操作函数
    7. } else {
    8. onFailure(); // 调用失败操作函数
    9. }
    10. }
    11. }
    12. handleResult(recv, "SetTime",&SystemManageWidget::showMessage( "设置时间操作成功!") ,&SystemManageWidget:: showMessage( "设置时间操作失败!") );
    13. error: cannot take the address of an rvalue of type 'void'
    14. 为什么不对
    15. 问题出在你试图传递成员函数 `SystemManageWidget::showMessage` 作为参数。成员函数需要与特定的实例关联,所以不能直接传递给一个通用函数。
    16. 为了解决这个问题,你可以使用 `std::function` 来包装成员函数并传递它们。下面是如何修改 `handleResult` 函数的方式:
    17. ```cpp
    18. template <typename T, typename FuncSuccess, typename FuncFailure>
    19. void SystemManageWidget::handleResult(const QJsonObject &recv, const T &key, FuncSuccess onSuccess, FuncFailure onFailure) {
    20. this->setEnabled(true);
    21. if (recv.contains(key)) {
    22. if (recv[key].toBool()) {
    23. onSuccess(); // 调用成功操作函数
    24. } else {
    25. onFailure(); // 调用失败操作函数
    26. }
    27. }
    28. }
    29. // 示例调用
    30. handleResult(recv, "SetTime",
    31. [this]() { showMessage("设置时间操作成功!"); },
    32. [this]() { showMessage("设置时间操作失败!"); }
    33. );
    34. ```
    35. 在示例调用中,使用了 lambda 函数来包装成员函数调用,以确保它们与当前的 `SystemManageWidget` 实例相关联。

    将多个数据封装成1个数据的方法

    1. 将多个数据封装成一个数据的好方法是使用结构(struct)或类(class),这取决于编程语言和需求。以下是一些方法:
    2. 1. **结构(Struct)**:
    3. - 结构是一种轻量级的数据类型,通常用于封装一组相关的数据字段。
    4. - 结构的成员变量可以是不同的数据类型,例如整数、字符串、浮点数等。
    5. - 适用于小型数据对象,不需要复杂的方法或成员函数。
    6. 示例(C++):
    7. ```cpp
    8. struct Person {
    9. std::string name;
    10. int age;
    11. double height;
    12. };
    13. ```
    14. 2. **类(Class)**:
    15. - 类是一种更强大的数据类型,允许封装数据字段和相关的操作方法(成员函数)。
    16. - 类的成员函数可以用于操作封装的数据,提供了更多的控制和封装性。
    17. - 适用于需要处理复杂对象,包括数据和行为的情况。
    18. 示例(C++):
    19. ```cpp
    20. class Person {
    21. private:
    22. std::string name;
    23. int age;
    24. double height;
    25. public:
    26. Person(const std::string &n, int a, double h) : name(n), age(a), height(h) {}
    27. void setName(const std::string &n) { name = n; }
    28. void setAge(int a) { age = a; }
    29. void setHeight(double h) { height = h; }
    30. std::string getName() const { return name; }
    31. int getAge() const { return age; }
    32. double getHeight() const { return height; }
    33. };
    34. ```
    35. 3. **字典(Dictionary)或映射(Map)**:
    36. - 如果你需要将一组数据关联到特定的键,可以使用字典或映射数据结构。
    37. - 这允许你通过键查找和访问相关的数据。
    38. 示例(Python):
    39. ```python
    40. person = {
    41. "name": "John",
    42. "age": 30,
    43. "height": 175.5
    44. }
    45. ```
    46. 4. **元组(Tuple)**:
    47. - 元组是一种不可变的数据结构,用于组合多个数据项。
    48. - 适用于不需要修改封装数据的情况。
    49. 示例(Python):
    50. ```python
    51. person = ("John", 30, 175.5)
    52. ```
    53. 5. **JSON或XML**:
    54. - 如果需要在多个应用程序或平台之间传递数据,可以使用JSON或XML格式来封装和序列化数据。
    55. 示例(JSON):
    56. ```json
    57. {
    58. "name": "John",
    59. "age": 30,
    60. "height": 175.5
    61. }
    62. ```
    63. 选择哪种方法取决于你的具体需求,例如数据大小、复杂性、是否需要操作方法等。不同的编程语言也提供了不同的工具和数据结构来实现数据封装。

    QT中将多个数据封装成1个数据的方法

    1. 在Qt中,你可以使用类(class)或结构体(struct)来将多个数据封装成一个数据。这通常依赖于你的需求和数据的性质。以下是一些方法:
    2. 1. **使用类(class)**:
    3. - 在Qt中,你可以创建一个自定义类,将多个数据成员存储在这个类中。
    4. - 使用类的优点是可以添加成员函数来执行操作和维护数据的封装性。
    5. - 这对于需要更多行为的数据对象非常有用。
    6. 示例(C++,Qt):
    7. ```cpp
    8. class Person {
    9. public:
    10. Person(const QString &name, int age, const QDate &birthDate)
    11. : m_name(name), m_age(age), m_birthDate(birthDate) {
    12. }
    13. QString name() const { return m_name; }
    14. int age() const { return m_age; }
    15. QDate birthDate() const { return m_birthDate; }
    16. private:
    17. QString m_name;
    18. int m_age;
    19. QDate m_birthDate;
    20. };
    21. ```
    22. 2. **使用结构体(struct)**:
    23. - 结构体是另一种用于封装数据的方式,它通常更轻量。
    24. - 结构体的成员可以是不同的数据类型,但没有成员函数。
    25. - 这适用于小型数据对象,不需要操作。
    26. 示例(C++,Qt):
    27. ```cpp
    28. struct Person {
    29. QString name;
    30. int age;
    31. QDate birthDate;
    32. };
    33. ```
    34. 3. **使用QVariantMap**:
    35. - Qt提供了QVariantMap作为一种通用数据容器,可以用于存储多个不同类型的数据。
    36. - 这对于将多个数据打包到一个对象中非常有用,而不需要定义自定义类。
    37. - 注意,QVariantMap需要手动处理数据类型的转换。
    38. 示例(C++,Qt):
    39. ```cpp
    40. QVariantMap personData;
    41. personData["name"] = "John";
    42. personData["age"] = 30;
    43. personData["birthDate"] = QDate(1992, 5, 15);
    44. ```
    45. 选择哪种方法取决于你的具体需求和项目的规模。如果需要更多的控制和操作,使用类可能更合适。如果只需存储和检索数据,结构体或QVariantMap可能足够。
    46. 4. **使用QPair和QMap**:
    47. - 如果你只需要将两个值配对,可以使用QPair。
    48. - 如果你有多个字段需要存储,可以使用QMap,其中键是字段名,值是字段值。
    49. 示例(QPair,C++,Qt):
    50. ```cpp
    51. QPairint> personData("John", 30);
    52. ```
    53. 示例(QMap,C++,Qt):
    54. ```cpp
    55. QMap personData;
    56. personData["name"] = "John";
    57. personData["age"] = 30;
    58. ```
    59. 5. **使用自定义数据结构**:
    60. - 你还可以自定义一个数据结构,不必使用Qt提供的类或结构体。
    61. - 这样可以更好地满足特定需求,例如使用数组、列表或其他数据容器。
    62. 示例(C++,Qt):
    63. ```cpp
    64. struct CustomData {
    65. QString name;
    66. int age;
    67. QDate birthDate;
    68. QVector<int> scores;
    69. };
    70. ```
    71. 6. **使用元组(Tuple)**:
    72. - C++11引入了元组,可以用来包装多个数据项。
    73. - 使用`std::tuple`可以创建具有不同数据类型的元组。
    74. 示例(C++11):
    75. ```cpp
    76. std::tupleint, QDate> personData("John", 30, QDate(1992, 5, 15));
    77. ```
    78. 上述方法中的每一种都有不同的优缺点,根据你的具体需求来选择最合适的方法。如果只需要简单地存储和检索数据,QVariantMap可能是一个不错的选择。如果需要更多的操作或具有复杂的数据结构,自定义类可能更合适。

    TCP UDP的基类

    1. #include
    2. #include
    3. #include
    4. class NetworkProtocolBase : public QObject
    5. {
    6. Q_OBJECT
    7. public:
    8. NetworkProtocolBase(QObject* parent = nullptr) : QObject(parent) {}
    9. // 公共接口用于连接和断开连接
    10. virtual bool connectToHost(const QString& host, quint16 port) = 0;
    11. virtual void disconnect() = 0;
    12. // 发送数据
    13. virtual qint64 send(const QByteArray& data) = 0;
    14. signals:
    15. // 接收到数据时发射的信号
    16. void dataReceived(const QByteArray& data);
    17. // 连接建立时发射的信号
    18. void connected();
    19. // 连接断开时发射的信号
    20. void disconnected();
    21. protected slots:
    22. // 接收数据的槽
    23. virtual void receiveData() = 0;
    24. };

    tabWidget当不是第一个页面时,发出信号,当回到第一个信号时发出信号.

    1. int previousTabIndex = 0; // 用于存储上一个选项卡的索引
    2. connect(tabWidget, &QTabWidget::currentChanged, this, &YourClass::onTabChanged);
    3. void YourClass::onTabChanged(int currentTabIndex)
    4. {
    5. if (currentTabIndex == 0 && previousTabIndex != 0) {
    6. // 当切换回第一个选项卡时发出信号
    7. emit returnedToFirstTab();
    8. } else if (currentTabIndex != 0 && previousTabIndex == 0) {
    9. // 当从第一个选项卡切换到其他选项卡时发出信号
    10. emit switchedFromFirstTab();
    11. }
    12. // 更新上一个选项卡的索引
    13. previousTabIndex = currentTabIndex;
    14. }

     tabWidget当不是第一个页面时,返回false,当回到第一个信号时返回true.

    1. connect(tabWidget, &QTabWidget::currentChanged, this, [this](int currentTabIndex) {
    2. TIME = (currentTabIndex == 0);
    3. });

     stackedWidget当不是第一个页面时,发出信号,当回到第一个信号时发出信号

    1. int previousPageIndex = 0; // 用于存储上一个页面的索引
    2. connect(stackedWidget, &QStackedWidget::currentChanged, this, [this](int currentPageIndex) {
    3. if (currentPageIndex == 0) {
    4. // 当切换回第一个页面时发出信号
    5. emit returnedToFirstPage();
    6. } else if (previousPageIndex == 0) {
    7. // 当从第一个页面切换到其他页面时发出信号
    8. emit switchedFromFirstPage();
    9. }
    10. // 更新上一个页面的索引
    11. previousPageIndex = currentPageIndex;
    12. });

    stackedWidget当不是第一个页面时,返回false,当回到第一个信号时返回true.

    1. connect(stackedWidget, &QStackedWidget::currentChanged, this, [this](int currentPageIndex) {
    2. TIME = (currentPageIndex == 0);
    3. });

    读取文件

    1. #include
    2. #include
    3. #include
    4. #include
    5. #include
    6. QString readTextFile(const QString &filePath) {
    7. QString fileContents;
    8. // 创建 QFile 对象并尝试打开文件
    9. QFile file(filePath);
    10. if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
    11. QTextStream in(&file);
    12. fileContents = in.readAll();
    13. file.close();
    14. } else {
    15. qDebug() << "无法打开文件:" << filePath;
    16. }
    17. return fileContents;
    18. }

    实时检测脚本文件的输出

    1. 如果你不需要继承自`QThread`的类,而只是想在主线程中使用`QProcess`运行脚本,可以直接使用`QProcess`和信号槽来实现。以下是相应的修改后的代码:
    2. ```cpp
    3. #include
    4. #include
    5. #include
    6. class ScriptRunner : public QObject
    7. {
    8. Q_OBJECT
    9. public:
    10. ScriptRunner(const QString& scriptPath, const QStringList& arguments) :
    11. scriptPath(scriptPath), arguments(arguments), processRunning(false)
    12. {
    13. // 初始化 QProcess
    14. process.setProgram(scriptPath);
    15. process.setArguments(arguments);
    16. // 连接进程的readyReadStandardOutput信号到槽函数
    17. connect(&process, &QProcess::readyReadStandardOutput, this, [=]() {
    18. // 读取进程输出
    19. QByteArray output = process.readAllStandardOutput();
    20. qDebug() << "脚本输出:" << output;
    21. // 发出输出信号
    22. emit scriptOutput(output);
    23. });
    24. // 连接进程的finished信号到槽函数
    25. connect(&process, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), this, [=](int exitCode, QProcess::ExitStatus exitStatus) {
    26. qDebug() << "进程退出码:" << exitCode;
    27. // 发出脚本运行结束信号
    28. emit scriptFinished(exitCode);
    29. processRunning = false;
    30. });
    31. }
    32. // 启动进程
    33. void startProcess()
    34. {
    35. if (!processRunning) {
    36. // 启动进程
    37. process.start();
    38. processRunning = true;
    39. }
    40. }
    41. // 关闭进程
    42. void stopProcess()
    43. {
    44. if (processRunning) {
    45. // 关闭进程
    46. process.kill();
    47. process.waitForFinished(-1);
    48. processRunning = false;
    49. }
    50. }
    51. public slots:
    52. // 向正在运行的进程发送指令
    53. void sendCommand(const QString& command)
    54. {
    55. if (processRunning) {
    56. // 向进程写入指令
    57. process.write(command.toUtf8());
    58. process.waitForBytesWritten();
    59. }
    60. }
    61. signals:
    62. // 发出输出信号
    63. void scriptOutput(const QByteArray& output);
    64. // 发出脚本运行结束信号
    65. void scriptFinished(int exitCode);
    66. private:
    67. QString scriptPath; // 脚本路径
    68. QStringList arguments; // 脚本参数
    69. QProcess process; // 外部进程
    70. bool processRunning; // 进程是否在运行
    71. };
    72. int main(int argc, char *argv[])
    73. {
    74. QCoreApplication a(argc, argv);
    75. // 创建 ScriptRunner 对象
    76. ScriptRunner scriptRunner("/path/to/your_acv_executable", {"arg1", "arg2", "arg3"});
    77. // 连接 ScriptRunner 的输出信号到槽函数
    78. QObject::connect(&scriptRunner, &ScriptRunner::scriptOutput, [](const QByteArray& output) {
    79. qDebug() << "Received Output:" << output;
    80. // 处理输出,例如显示在界面上
    81. // 在接收到数据后,向正在运行的进程发送指令
    82. scriptRunner.sendCommand("your_command_here");
    83. });
    84. // 连接 ScriptRunner 的脚本运行结束信号到槽函数
    85. QObject::connect(&scriptRunner, &ScriptRunner::scriptFinished, [&](int exitCode) {
    86. qDebug() << "Script Finished with Exit Code:" << exitCode;
    87. // 处理脚本运行结束
    88. a.quit(); // 结束应用程序事件循环
    89. });
    90. // 启动 ScriptRunner
    91. scriptRunner.startProcess();
    92. // 进入主线程的事件循环
    93. return a.exec();
    94. }
    95. ```
    96. 这个版本的代码使用了主线程,而不是继承自`QThread`的自定义线程类。

     你是一个精通设计模式的老程序员,请设计一个QT类,他的作用是创建一个QProcess,并至少有下面的函数“启动QProcess”,“监听接收来自QProcess的消息并发出信号”,“向QProcess发送消息”,“关闭QProcess”

    当设计一个包含启动、监听、发送消息和关闭功能的QProcess管理类时,你可以创建一个自定义的类,例如 ProcessManager。下面是一个简单的实现:

    1. // processmanager.h
    2. #ifndef PROCESSMANAGER_H
    3. #define PROCESSMANAGER_H
    4. #include
    5. #include
    6. class ProcessManager : public QObject
    7. {
    8. Q_OBJECT
    9. public:
    10. explicit ProcessManager(QObject *parent = nullptr);
    11. ~ProcessManager();
    12. // 启动QProcess
    13. void startProcess(const QString &program, const QStringList &arguments = QStringList());
    14. signals:
    15. // 信号:接收来自QProcess的消息
    16. void processMessageReceived(const QString &message);
    17. public slots:
    18. // 向QProcess发送消息
    19. void sendMessageToProcess(const QString &message);
    20. // 关闭QProcess
    21. void closeProcess();
    22. private slots:
    23. // 处理QProcess的输出
    24. void processReadyRead();
    25. private:
    26. QProcess *process;
    27. };
    28. #endif // PROCESSMANAGER_H
    1. // processmanager.cpp
    2. #include "processmanager.h"
    3. ProcessManager::ProcessManager(QObject *parent)
    4. : QObject(parent)
    5. {
    6. // 初始化 QProcess 对象
    7. process = new QProcess(this);
    8. // 连接信号槽,处理 QProcess 的输出
    9. connect(process, &QProcess::readyReadStandardOutput, this, &ProcessManager::processReadyRead);
    10. }
    11. ProcessManager::~ProcessManager()
    12. {
    13. // 在析构函数中关闭 QProcess
    14. closeProcess();
    15. }
    16. void ProcessManager::startProcess(const QString &program, const QStringList &arguments)
    17. {
    18. // 启动 QProcess
    19. process->start(program, arguments);
    20. }
    21. void ProcessManager::sendMessageToProcess(const QString &message)
    22. {
    23. // 向 QProcess 发送消息
    24. if (process->state() == QProcess::Running)
    25. process->write(message.toUtf8());
    26. }
    27. void ProcessManager::closeProcess()
    28. {
    29. // 关闭 QProcess
    30. if (process->state() == QProcess::Running)
    31. process->terminate();
    32. }
    33. void ProcessManager::processReadyRead()
    34. {
    35. // 读取 QProcess 的输出,并发出信号
    36. QString output = QString::fromUtf8(process->readAllStandardOutput());
    37. emit processMessageReceived(output);
    38. }

     这个类中包含了启动、监听、发送消息和关闭 QProcess 的功能。你可以在你的应用程序中实例化 ProcessManager 类,然后连接 processMessageReceived 信号来接收来自 QProcess 的消息。使用 sendMessageToProcess 函数可以向 QProcess 发送消息,而 closeProcess 函数用于关闭 QProcess。

    延时函数 

    1. void Delay_MSec(unsigned int msec)
    2. {
    3. QEventLoop loop;//定义一个新的事件循环
    4. QTimer::singleShot(msec, &loop, SLOT(quit())); //创建单次定时器,槽函数为事件循环的退出函数
    5. loop.exec(); //事件循环开始执行,程序会卡在这里,直到定时时间到,本循环被退出
    6. }

  • 相关阅读:
    MMDetecion 安装流程
    sql server 设置字段自增
    Jboss反序列化漏洞
    基于Python实现Midjourney集成到(个人/公司)平台中
    Python之numpy数组篇(上)
    智云通CRM:销售的黄金法则,尊重客户的意见
    【LeetCode】二分查找题解汇总
    【MATLAB源码-第68期】基于matlab的802.11b 11Mbps CCK调制解调误码率仿真。
    昇腾AI与“紫东.太初”赋能法律服务,多模态大模型迈向“多专多能”
    【全网唯一有效】MacOS 12.4安装Parallels Desktop 17.1.x出现网络错误等等解决
  • 原文地址:https://blog.csdn.net/weixin_44783692/article/details/133045082