- void MainWindow::on_pushButton_5_clicked()
-
- {
-
- // 锁定界面
-
- setWidgetsEnabled(ui->centralwidget, false);
-
-
-
- // 创建一个定时器,等待3秒后解锁界面
-
- QTimer::singleShot(3000, this, [=]() {
-
- setWidgetsEnabled(ui->centralwidget, true);;//ui->centralwidget这个是全局布局
-
- });
-
-
-
- }
-
- // 将界面的所有控件禁用或启用
-
- void MainWindow::setWidgetsEnabled(QWidget *widget, bool enabled) {
-
- if (widget) {
-
- for (auto child : widget->findChildren
()) { -
- if (child->isWidgetType()) {
-
- child->setEnabled(enabled);
-
- qDebug() << "Widget:" << child->objectName() << "Enabled:" << enabled;
-
-
-
- }
-
- }
-
- }
-
- }
- void MainWindow::read_init()
- {
-
- QSettings settings("myapp.ini", QSettings::IniFormat);
- if (!settings.contains("server/port")) {
- // 如果不存在,才写入配置项
- settings.setValue("server/port", "8080");
- }
- server_PortStr = settings.value("server/port").toString();
- qDebug() << "port:" << server_PortStr;
- }
发送方
dialog.h
- signals:
- void dataEntered(const QString &data);
-
dialog.c
emit dataEntered(ipAddress);
接收方
mainwindow.h
- private slots:
- void receiveData(const QString &data);
- private:
- Dialog *dialog;
mainwindow.cpp
- MainWindow::MainWindow(QWidget *parent)
- : QMainWindow(parent)
- , ui(new Ui::MainWindow)
- {
- ui->setupUi(this);
- dialog= new Dialog();
- connect(dialog, SIGNAL(dataEntered(QString)), this, SLOT(receiveData(QString)));
- }
-
-
- void MainWindow::receiveData(const QString &data) {
- // 在这里处理接收到的数据
- server_IP=data;
- qDebug() << "Received data in MainWindow:" << server_IP;
- //插入新行
- int currentRow = ui->tableWidget->rowCount();
- qDebug() << "currentRow" << currentRow;
- ui->tableWidget->insertRow(currentRow);
- // 创建一个 QTableWidgetItem 对象并设置文本
- QTableWidgetItem *item1 = new QTableWidgetItem(QString::number(currentRow + 1)); // 设置序号
- QTableWidgetItem *item2 = new QTableWidgetItem(server_IP); // 设置数据
- // 插入 QTableWidgetItem 到指定行和列
- ui->tableWidget->setItem(currentRow, 0, item1); // 设置第一列的单元格为序号
- ui->tableWidget->setItem(currentRow, 1, item2); // 设置第二列的单元格为数据
- }
-
-
-
- void MainWindow::sendAndReceiveData(const QByteArray &sendData, QByteArray &receivedData, const QString &serverIP) {
- // 将字符串形式的端口号转换为整数
- bool ok;
- quint16 serverPort = server_PortStr.toUShort(&ok);
- if (!ok) {
- qDebug() << "Invalid port number:" << server_PortStr;
- return; // 如果端口号无效,函数直接返回
- }
-
- // 将字符串形式的IP地址转换为QHostAddress
- QHostAddress serverAddress(serverIP);
-
- // 发送数据到服务器
- udpSocket->writeDatagram(sendData, serverAddress, serverPort);
-
- // 接收服务器的回复
- QByteArray responseData;
- while (udpSocket->waitForReadyRead()) {
- responseData.resize(udpSocket->pendingDatagramSize());
- QHostAddress senderAddress;
- quint16 senderPort;
- udpSocket->readDatagram(responseData.data(), responseData.size(), &senderAddress, &senderPort);
-
- MainWindow::~MainWindow()
- {
- //关闭套接字,并丢弃写缓冲区中的所有待处理数据。
- // udpSocket->abort();
- delete ui;
- }
-
- // 将接收到的数据存储到传入的receivedData变量中
- receivedData = responseData;
- qDebug() << "Received response from server" << senderAddress.toString() << "on port" << senderPort;
- qDebug() << "Response Data:" << responseData;
- }
- }
或
- bool WorkThread::udpCommunicate(const QJsonObject &sendData,
- QJsonObject &receivedData,
- const QString &localIp,
- quint16 localPort,
- const QString &serverIp,
- quint16 serverPort)
- {
- // 创建 UDP 套接字
- QUdpSocket udpSocket;
-
- // 绑定本地 IP 和端口
- if (!udpSocket.bind(QHostAddress(localIp), localPort)) {
- qDebug() << "Failed to bind to local address and port";
- return false;
- }
-
- // 构造要发送的 JSON 数据
- QJsonDocument sendDoc(sendData);
- QByteArray sendByteArray = sendDoc.toJson(QJsonDocument::Compact);
-
- // 发送数据到服务器
- udpSocket.writeDatagram(sendByteArray, QHostAddress(serverIp), serverPort);
-
- while (true) {
- if (udpSocket.hasPendingDatagrams()) {
- QByteArray receivedByteArray;
- receivedByteArray.resize(udpSocket.pendingDatagramSize());
- udpSocket.readDatagram(receivedByteArray.data(), receivedByteArray.size());
-
- // 解析接收到的 JSON 数据
- QJsonParseError parseError;
- QJsonDocument receivedDoc = QJsonDocument::fromJson(receivedByteArray, &parseError);
- if (parseError.error != QJsonParseError::NoError) {
- qDebug() << "Failed to parse received JSON data:" << parseError.errorString();
- return false;
- }
-
- // 将接收到的 JSON 数据转换为 QJsonObject
- receivedData = receivedDoc.object();
-
- // 关闭套接字
- udpSocket.close();
-
- return true;
- }
- }
- }
在项目文件创建一个文件styles.qss,然后在qt资源文件打开现有文件即可
然后代码加载;
建议要用样式表都用样式表
具体的样式比样式表级别高(具体样式背景影响样式表控件的样式)
加载样式表在main函数里加载
- int main(int argc, char *argv[])
- {
- QApplication a(argc, argv);
- // 加载样式表文件
-
- QFile styleFile(":/new/styles.qss"); // 样式表文件的路径
- if (styleFile.open(QFile::ReadOnly | QFile::Text)) {
- QTextStream stream(&styleFile);
- QString style = stream.readAll();
- a.setStyleSheet(style); // 应用样式表
- styleFile.close();
- }
-
- MainWindow w;
- w.show();
- return a.exec();
- }
- class WorkerThread : public QThread
- {
- Q_OBJECT
- public:
- WorkerThread() : shouldStop(false) {}
-
- void stopThread() {
- shouldStop = true;
- }
-
- protected:
- void run() override {
- //运行代码
- }
-
- private:
- bool shouldStop;
-
- };
- void MainWindow::on_pushButton_clicked()
- {
- // 创建 WorkerThread 对象并连接 finished 信号
- workerThread = new WorkerThread;
- QObject::connect(workerThread, &QThread::finished, [&]() {
- // 后台线程完成时设置按钮文本
- ui->pushButton->setEnabled(true);
- ui->pushButton->setText("刷新状态");
-
- // 释放 WorkerThread 对象
- workerThread->deleteLater();
- });
-
- // 点击按钮后设置按钮文本为 "刷新中..."
- ui->pushButton->setText("刷新中...");
- ui->pushButton->setEnabled(false);
-
- // 启动后台线程执行循环
- workerThread->start();
-
- }
-
- void MainWindow::on_pushButton_6_clicked()
- {
- // 获取选中的行
- int selectedRow = ui->tableWidget->currentRow();
-
- if (selectedRow >= 0) {
- // 检查第八列是否为空
- QTableWidgetItem *item8 = ui->tableWidget->item(selectedRow, 7); // 第八列索引为7
- bool isEmptyColumn8 = item8 && item8->text().isEmpty();
-
- // 检查其他列是否都不为空
- bool isOtherColumnsNotEmpty = true;
- for (int column = 0; column < ui->tableWidget->columnCount(); ++column) {
- if (column != 7) { // 排除第八列
- QTableWidgetItem *item = ui->tableWidget->item(selectedRow, column);
- if (!item || item->text().isEmpty()) {
- isOtherColumnsNotEmpty = false;
- break;
- }
- }
- }
-
- // 创建灰色文本颜色
- QColor grayColor = QColor("#8c8c8c");
-
- // 如果第八列为空且其他列都不为空,将第八列的数据设置为 "已启用" 并设置文本颜色为灰色
- if (isEmptyColumn8 && isOtherColumnsNotEmpty) {
- QTableWidgetItem *newItem = new QTableWidgetItem("已启用");
- newItem->setForeground(QBrush(grayColor)); // 设置文本颜色为灰色
- ui->tableWidget->setItem(selectedRow, 7, newItem);
- } else {
- QTableWidgetItem *newItem = new QTableWidgetItem("未启用");
- newItem->setForeground(QBrush(grayColor)); // 设置文本颜色为灰色
- ui->tableWidget->setItem(selectedRow, 7, newItem);
- }
- }
-
- }
-
- // 获取临时文件的完整路径
- QString tempFilePath = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/temp_data.txt";
-
- // 在程序启动时加载临时文件中的数据
- void MainWidget::loadTempFileData() {
- QFile file(tempFilePath); // 使用完整路径
- if (file.exists()) {
- if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
- QTextStream in(&file);
- while (!in.atEnd()) {
- QString line = in.readLine();
- QStringList rowData = line.split(","); // 假设数据以逗号分隔
- if (rowData.size() == 3) {
- // 将每行数据添加到QTableWidget中的三列
- ui->tableWidget->insertRow(ui->tableWidget->rowCount());
- for (int column = 0; column < 3; ++column) {
- QTableWidgetItem *item = new QTableWidgetItem(rowData[column]);
- ui->tableWidget->setItem(ui->tableWidget->rowCount() - 1, column, item);
- }
- }
- }
- file.close();
- }
- }
- }
-
- // 在添加新行数据时,同时将所有数据写入临时文件
- void MainWidget::addRowToTableWidget(const QString &rowData) {
- // 将新行数据添加到QTableWidget中的三列
- ui->tableWidget->insertRow(ui->tableWidget->rowCount());
-
- QStringList rowDataList = rowData.split(","); // 使用逗号分隔字段
- for (int column = 0; column < 3; ++column) {
- if (column < rowDataList.size()) {
- QTableWidgetItem *item = new QTableWidgetItem(rowDataList[column]);
- ui->tableWidget->setItem(ui->tableWidget->rowCount() - 1, column, item);
- }
- }
-
- // 写入所有数据到临时文件
- QFile file(tempFilePath); // 使用完整路径
- if (file.open(QIODevice::WriteOnly | QIODevice::Text)) {
- QTextStream out(&file);
- // 遍历QTableWidget中的数据,将每行数据写入文件
- for (int row = 0; row < ui->tableWidget->rowCount(); ++row) {
- QStringList rowData;
- for (int column = 0; column < 3; ++column) {
- QTableWidgetItem *item = ui->tableWidget->item(row, column);
- if (item) {
- rowData << item->text();
- }
- }
- out << rowData.join(",") << "\n";
- }
- file.close();
- }
- }
- // 清空临时文件
- void MainWidget::clearTempFile() {
- QFile file(tempFilePath); // 使用完整路径
- if (file.exists()) {
- if (file.remove()) {
- qDebug() << "临时文件已成功清空.";
- } else {
- qDebug() << "无法清空临时文件.";
- }
- } else {
- qDebug() << "临时文件不存在.";
- }
- }
- #include
- #include
- #include
-
- int main(int argc, char *argv[]) {
- QCoreApplication a(argc, argv);
-
- // 创建一个定时器
- QTimer timer;
- timer.setSingleShot(true); // 设置定时器为单次触发
- timer.start(5000); // 设置超时时间为5秒
-
- // 使用事件循环等待定时器超时
- QEventLoop loop;
- QObject::connect(&timer, &QTimer::timeout, &loop, &QEventLoop::quit); // 当定时器超时时退出事件循环
-
- // 死循环,等待定时器超时
- while (true) {
- // 如果定时器超时,退出循环
- if (!timer.isActive()) {
- break;
- }
-
- // 处理其他任务
- // 这里可以添加需要执行的操作,确保不会阻塞事件循环
-
- // 处理事件,确保事件循环继续运行
- QCoreApplication::processEvents();
- }
-
- // 此处可以执行定时器超时后需要执行的操作
-
- return a.exec();
- }
- void SystemManageWidget::writeini(const QString &key, const QString &value)
- {
- // 创建QSettings对象来操作配置文件
- const QString filePath="D:/devConfig.ini";
- QSettings settings(filePath, QSettings::IniFormat);
-
- // 在配置文件中创建一条信息
- settings.setValue(key, value);
-
- // 保存更改
- settings.sync();
- }
- QString SystemManageWidget::readini(const QString &key)
- {
- // 创建QSettings对象来操作配置文件
- const QString filePath = "D:/devConfig.ini";
- QSettings settings(filePath, QSettings::IniFormat);
-
- // 使用提供的键获取配置文件中的值
- return settings.value(key).toString();
-
- }
- void SystemManageWidget::UDP(QJsonObject &sendobj,QString &sever_ip){
- QJsonObject recv;
-
- QSettings *settings = new QSettings("D:/devConfig.ini", QSettings::Format::IniFormat);
- // ip=settings.value("ip").toString();
- QString client_port = settings->value("local_port").toString();
- QString Ui_port = settings->value("Ui_port").toString();
- QString client_ip=settings->value("client_ip").toString();
- QString severs_port=settings->value("UI_port").toString();
-
- qDebug()<<"severs_port"<
- qDebug()<<"client_port"<
- qDebug()<<"client_ip"<
-
- QByteArray send;
- QByteArray rec;
- QJsonDocument senddoc(sendobj);
- send=senddoc.toJson();
- QUdpSocket udp_socket;
- udp_socket.bind(QHostAddress(client_ip),client_port.toUShort());
- udp_socket.writeDatagram(send,QHostAddress(sever_ip),severs_port.toUShort());
- QHostAddress a;
- ushort aa;
-
- QTimer time;
- time.setSingleShot(true);
- time.start(5000);
- QEventLoop loop;
- connect(&time,&QTimer::timeout,&loop,&QEventLoop::quit);
-
-
- while(1){
- rec.resize(udp_socket.pendingDatagramSize());
- udp_socket.readDatagram(rec.data(),rec.size(),&a,&aa);
-
- if(!rec.isEmpty()){
- qDebug()<<"port"<
- qDebug()<<"size"<
size(); - qDebug()<<"data"<
data(); -
- QJsonDocument recdoc=QJsonDocument::fromJson(rec);
- recv=recdoc.object();
- break;
- }
- if (!time.isActive()) {
- qDebug() << "Timeout occurred."; // 超时处理
-
- break;
- }
- // 处理事件
- loop.processEvents();
- }
- //接收处理
-
- if(recv.contains("SystemMessage")&&recv["SystemMessage"].toBool()){}
- if(recv.contains("Reset")&&recv["Reset"].toBool()){}
- if(recv.contains("Restart")&&recv["Restart"].toBool()){}
- if(recv.contains("BackUp")){}
- }
弹窗
- QMessageBox::StandardButton reply;
- reply = QMessageBox::question(
- nullptr,
- "提示",
- "是否进行备份设置操作?",
- QMessageBox::Yes | QMessageBox::No
- );
-
- if (reply == QMessageBox::Yes) {
-
-
-
- } else {
- // 用户点击了取消按钮或关闭了弹窗,不执行备份设置操作
-
- }
保存路径
- QString saveFilePath = QFileDialog::getSaveFileName(this, tr("选择保存位置"), "", tr("Batch Files (*.dat);;All Files (*)"));
- std::string filePath = saveFilePath.toStdString();
- std::string data1 = data.toStdString();
- if (!saveFilePath.isEmpty()) {
- // 打开文件以写入数据
- writeini("BackUpFilePath",saveFilePath);
- std::ofstream outputFile(filePath);
-
- if (outputFile.is_open()) {
- // 将数据写入文件
- outputFile << data1;
-
- // 关闭文件
- outputFile.close();
-
- std::cout << "数据已成功写入文件:" << filePath << std::endl;
-
-
-
- } else {
- std::cerr << "无法打开文件:" << filePath << std::endl;
- }
- }
弹窗1
- void showSuccessMessage(const QString &title, const QString &message)
- {
- QMessageBox messageBox;
- messageBox.setIcon(QMessageBox::Information);
- messageBox.setWindowTitle(title);
- messageBox.setText(message);
- messageBox.setStandardButtons(QMessageBox::Ok);
-
- messageBox.exec();
- }
弹窗2
- #include
-
- int showCustomConfirmationDialog(const QString &title, const QString &message, const QString &okButtonText, const QString &cancelButtonText)
- {
- QMessageBox messageBox;
- messageBox.setIcon(QMessageBox::Warning);
- messageBox.setWindowTitle(title);
- messageBox.setText(message);
- messageBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
- messageBox.setButtonText(QMessageBox::Ok, okButtonText);
- messageBox.setButtonText(QMessageBox::Cancel, cancelButtonText);
-
- return messageBox.exec();
- }
-
- // 使用示例
- void yourFunction()
- {
- int choice = showCustomConfirmationDialog("自定义标题", "您确定要执行此操作吗?", "确认", "取消");
-
- if (choice == QMessageBox::Ok) {
- // 用户点击了确认按钮,执行相关操作
- // 在这里添加您的操作代码
- } else if (choice == QMessageBox::Cancel) {
- // 用户点击了取消按钮,执行其他操作
- // 在这里添加您的操作代码
- }
- }
-
3s弹窗
- #include
- #include
-
- // ...
-
- void SystemManageWidget::showTemporaryMessageBox(QString a)
- {
- QMessageBox messageBox;
- messageBox.setIcon(QMessageBox::Information); // 设置图标为信息图标
- messageBox.setWindowTitle(""); // 设置对话框标题
- messageBox.setText(a); // 设置消息文本
-
- QTimer timer;
- timer.setSingleShot(true); // 设置为单次触发
- timer.setInterval(3000); // 设置定时器间隔为3秒(3000毫秒)
-
- QObject::connect(&timer, &QTimer::timeout, [&messageBox]() {
- messageBox.close(); // 定时器触发后关闭消息框
- });
-
- messageBox.show(); // 显示消息框
- timer.start(); // 启动定时器
- Delay(3000);
- }
- void SystemManageWidget::Delay(int msec)
- { // 这个最准
- /*非阻塞方式延时,现在很多人推荐的方法*/
- QEventLoop loop;
- QTimer::singleShot(msec, &loop, SLOT(quit()));
- loop.exec();
- }
选择文件路径
- #include
-
- // ...
-
- QString filePath = QFileDialog::getOpenFileName(this, "选择文件", "", "所有文件 (*.*);;文本文件 (*.txt);;图像文件 (*.png *.jpg)");
-
- if (!filePath.isEmpty()) {
- // 用户选择了文件,filePath包含所选文件的路径
- // 在这里可以对所选文件执行操作
- } else {
- // 用户取消了选择操作
- }
将tablewight所有内容导出与导入
- void GeneralPolicyWidget::on_pushButton_3_clicked()
- {
- QString filePath = QFileDialog::getOpenFileName(this, "选择文件", "", tr("Batch Files (*.csv);;All Files (*)"));
- importCSVToTableWidget(filePath,ui->tableWidget);
- }
-
- void GeneralPolicyWidget::on_pushButton_4_clicked()
- {
- QString saveFilePath = QFileDialog::getSaveFileName(this, tr("选择保存位置"), "", tr("Batch Files (*.csv);;All Files (*)"));
- exportTableWidgetToCSV(ui->tableWidget,saveFilePath);
- }
- void GeneralPolicyWidget::exportTableWidgetToCSV(QTableWidget *tableWidget, const QString &filePath)
- {
- QFile file(filePath);
-
- if (file.open(QIODevice::WriteOnly | QIODevice::Text))
- {
- QTextStream stream(&file);
-
- // 写入表头
- QStringList headers;
- for (int col = 0; col < tableWidget->columnCount(); col++)
- {
- headers << tableWidget->horizontalHeaderItem(col)->text();
- }
- stream << headers.join(",") << "\n";
-
- // 写入表格数据
- for (int row = 0; row < tableWidget->rowCount(); row++)
- {
- QStringList rowData;
- for (int col = 0; col < tableWidget->columnCount(); col++)
- {
- QTableWidgetItem *item = tableWidget->item(row, col);
- if (item)
- {
- rowData << item->text();
- }
- else
- {
- rowData << "";
- }
- }
- stream << rowData.join(",") << "\n";
- }
-
- file.close();
- }
- else
- {
- // 打开文件失败,可以在此处理错误
- }
- }
-
-
- void GeneralPolicyWidget::importCSVToTableWidget(const QString &filePath, QTableWidget *tableWidget)
- {
- QFile file(filePath);
-
- if (file.open(QIODevice::ReadOnly | QIODevice::Text))
- {
- QTextStream stream(&file);
-
- int rowCount = 0; // 用于计算行数
-
- // 读取CSV文件的每一行
- while (!stream.atEnd())
- {
- QString line = stream.readLine();
- QStringList fields = line.split(","); // 使用逗号分隔字段
-
- // 跳过空行
- if (fields.isEmpty()) {
- continue;
- }
-
- // 创建新行并填充数据
- if (rowCount == 0) // 第一行作为表头
- {
- tableWidget->setColumnCount(fields.count());
- tableWidget->setHorizontalHeaderLabels(fields);
- }
- else // 其他行作为数据
- {
- int row = tableWidget->rowCount();
- tableWidget->insertRow(row);
- for (int col = 0; col < fields.count(); col++)
- {
- QTableWidgetItem *item = new QTableWidgetItem(fields[col]);
- tableWidget->setItem(row, col, item);
- }
- }
-
- rowCount++;
- }
-
- file.close();
- }
- else
- {
- // 打开文件失败,可以在此处理错误
- }
- }
UDP线程
- #include
- #include
- #include
-
- class UdpReceiver : public QObject
- {
- Q_OBJECT
-
- public slots:
- void processPendingDatagrams()
- {
- while (udpSocket.hasPendingDatagrams())
- {
- QByteArray datagram;
- datagram.resize(udpSocket.pendingDatagramSize());
- QHostAddress sender;
- quint16 senderPort;
-
- udpSocket.readDatagram(datagram.data(), datagram.size(), &sender, &senderPort);
-
- // 根据接收到的消息内容执行不同的功能
- if (datagram == "Message1")
- {
- // 执行功能1
- }
- else if (datagram == "Message2")
- {
- // 执行功能2
- }
- // 添加更多的消息处理逻辑
-
- qDebug() << "Received datagram:" << datagram;
- }
- }
-
- private:
- QUdpSocket udpSocket;
- };
-
- int main(int argc, char *argv[])
- {
- QCoreApplication a(argc, argv);
-
- UdpReceiver udpReceiver;
-
- // 创建UDP套接字并绑定到指定端口
- if (!udpReceiver.udpSocket.bind(QHostAddress::Any, 12345))
- {
- qDebug() << "Failed to bind UDP socket!";
- return 1;
- }
-
- // 连接信号和槽
- QObject::connect(&udpReceiver.udpSocket, SIGNAL(readyRead()), &udpReceiver, SLOT(processPendingDatagrams()));
-
- // 创建并启动独立线程
- QThread udpThread;
- udpReceiver.moveToThread(&udpThread);
- udpThread.start();
-
- return a.exec();
- }
-
数据库增删改操作
- class DataRecord {
- public:
- DataRecord(const QString &name = QString(),
- const QString &dizhi = QString(),
- const QString &dongzuo = QString(),
- const QString &fengzhuang = QString(),
- const QString &suanfa = QString())
- : name(name), dizhi(dizhi), dongzuo(dongzuo), fengzhuang(fengzhuang), suanfa(suanfa) {}
-
- QString name;
- QString dizhi;
- QString dongzuo;
- QString fengzhuang;
- QString suanfa;
- };
-
-
-
-
-
-
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- static QSqlDatabase db_strategy;
- bool MulticastPolicyWidget::connectToDatabase()
- {
-
- // 初始化数据库连接
- db_strategy = QSqlDatabase::addDatabase("QSQLITE");
- db_strategy.setDatabaseName("strategy.db"); // 数据库文件的名称,替换为你想要的名称
-
- // 打开数据库连接
- if (!db_strategy.open()) {
- qDebug() << "Failed to open database:" << db_strategy.lastError().text();
- return 1;
- }
-
- // 创建表格并执行 SQL 语句来初始化数据库
- QSqlQuery query;
- query.exec("CREATE TABLE IF NOT EXISTS zuboguanli ("
- "name text primary key,"
- "dizhi TEXT,"
- "dongzuo TEXT,"
- "fengzhuang TEXT,"
- "suanfa TEXT"
- ")");
-
- // 检查 SQL 查询是否执行成功
- if (query.lastError().isValid()) {
- qDebug() << "Database query error:" << query.lastError().text();
- return 1;
- }
-
- // 关闭数据库连接(如果需要的话)
- // db_strategy.close();
- }
- // 增加数据
- bool MulticastPolicyWidget::addDataToDatabase(const DataRecord &record) {
- QSqlQuery query(db_strategy);
- query.prepare("INSERT INTO zuboguanli (name, dizhi,dongzuo,fengzhuang,suanfa) VALUES (?, ?, ?, ?, ?)");
- query.bindValue(0, record.name);
- query.bindValue(1, record.dizhi);
- query.bindValue(2, record.dongzuo);
- query.bindValue(3, record.fengzhuang);
- query.bindValue(4, record.suanfa);
- if (query.exec()) {
- qDebug() << "成功插入数据";
- return true;
- } else {
- qDebug() << "插入数据失败:" << query.lastError().text();
- return false;
- }
- }
-
- // 删除数据
- bool MulticastPolicyWidget::deleteDataFromDatabase(const QString &name) {
- QSqlQuery query(db_strategy);
- query.prepare("DELETE FROM zuboguanli WHERE name = ?");
- query.bindValue(0, name);
-
- if (query.exec()) {
- qDebug() << "成功删除数据";
- return true;
- } else {
- qDebug() << "删除数据失败:" << query.lastError().text();
- return false;
- }
- }
-
- // 修改数据
- bool MulticastPolicyWidget::updateDataInDatabase(const DataRecord &record) {
- QSqlQuery query(db_strategy);
- query.prepare("UPDATE zuboguanli SET dizhi = ?, dongzuo = ?, fengzhuang = ?, suanfa = ? WHERE name = ?");
- query.bindValue(0, record.dizhi);
- query.bindValue(1, record.dongzuo);
- query.bindValue(2, record.fengzhuang);
- query.bindValue(3, record.suanfa);
- query.bindValue(4, record.name);
-
- if (query.exec()) {
- qDebug() << "成功更新数据";
- return true;
- } else {
- qDebug() << "更新数据失败:" << query.lastError().text();
- return false;
- }
- }
-
- //数据库打印到表
- void MulticastPolicyWidget::printTableDataToTableWidget(const QString &tableName, QTableWidget *tableWidget) {
- // 清空表格中的数据
- tableWidget->setRowCount(0);
-
- // 执行查询获取指定表的所有数据
- QSqlQuery query;
- query.exec(QString("SELECT * FROM %1").arg(tableName));
-
- // 设置表格的列数
- if (query.isActive()) {
- int columnCount = query.record().count();
- tableWidget->setColumnCount(columnCount);
-
- // 逐行填充数据
- int rowCount = 0;
- while (query.next()) {
- tableWidget->insertRow(rowCount);
- for (int col = 0; col < columnCount; col++) {
- tableWidget->setItem(rowCount, col, new QTableWidgetItem(query.value(col).toString()));
- }
- rowCount++;
- }
- } else {
- // 查询失败,可以在此处理错误
- }
- }
-
-
-
-
- //数据库转json
- QJsonDocument MulticastPolicyWidget::tableDataToJson(const QString &tableName) {
- // 创建一个 JSON 数组来存储表中的数据
- QJsonArray jsonArray;
-
- // 执行查询获取指定表的所有数据
- QSqlQuery query;
- query.exec(QString("SELECT * FROM %1").arg(tableName));
-
- // 将查询结果转换为 JSON 数组
- if (query.isActive()) {
- int columnCount = query.record().count();
- while (query.next()) {
- QJsonObject jsonObject;
- for (int col = 0; col < columnCount; col++) {
- QString columnName = query.record().fieldName(col);
- QVariant columnValue = query.value(col);
- jsonObject[columnName] = QJsonValue::fromVariant(columnValue);
- }
- jsonArray.append(jsonObject);
- }
- } else {
- // 查询失败,可以在此处理错误
- }
-
- // 创建一个 JSON 文档并返回
- QJsonDocument jsonDocument(jsonArray);
- return jsonDocument;
- }
-
- //获取界面文本
- DataRecord MulticastPolicyWidget::createDataRecordFromUI() {
-
- QString name = ui->lineEdit->text();
- QString dizhi = ui->lineEdit_2->text();
- QString dongzuo = ui->comboBox->currentText();
- QString fengzhuang = ui->comboBox_2->currentText();
- QString suanfa = ui->comboBox_3->currentText();
- DataRecord record(name, dizhi, dongzuo, fengzhuang, suanfa);
- return record;
- }
输入弹窗
- #include
-
- DataRecord MulticastPolicyWidget::createDataRecordFromUIid() {
- // 使用QInputDialog获取用户输入的ID
- bool ok;
- QString id = QInputDialog::getText(this, "输入ID", "请输入ID:", QLineEdit::Normal, QString(), &ok);
-
- if (ok) {
- // 用户点击了"确定"按钮
- DataRecord record(id);
- return record;
- } else {
- // 用户点击了"取消"按钮或关闭了输入对话框
- // 返回一个空的DataRecord或者根据需要进行处理
- return DataRecord();
- }
- }
我的
- #include "multicastpolicywidget.h"
- #include "ui_multicastpolicywidget.h"
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include "QInputDialog"
- #include "QVBoxLayout"
- static QSqlDatabase db_strategy;
- MulticastPolicyWidget::MulticastPolicyWidget(QWidget *parent) :
- QWidget(parent),
- ui(new Ui::MulticastPolicyWidget)
- {
- ui->setupUi(this);
- //动作
- ui->comboBox->addItem("加密");
- ui->comboBox->addItem("透传");
- ui->comboBox->addItem("丢弃");
- //封装模式
- ui->comboBox_2->addItem("线速(传输模式)");
- ui->comboBox_2->addItem("线速(隧道模式)");
- ui->comboBox_2->addItem("统型模式");
- //算法选择
- ui->comboBox_3->addItem("专核");
- ui->comboBox_3->addItem("普密");
- connectToDatabase();
- ui->tableWidget->verticalHeader()->setVisible(false);
- //ui->tableWidget->setShowGrid(false); // 默认情况下就是显示网格
- ui->tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
- ui->tableWidget->setColumnCount(5);
- ui->tableWidget_2->verticalHeader()->setVisible(false);
- //ui->tableWidget->setShowGrid(false); // 默认情况下就是显示网格
- ui->tableWidget_2->setEditTriggers(QAbstractItemView::NoEditTriggers);
- ui->tableWidget_2->verticalHeader()->setVisible(false); // 隐藏垂直表头
- ui->tableWidget_2->horizontalHeader()->setVisible(false); //
- ui->tableWidget_2->setRowCount(0);
- ui->tableWidget_2->setColumnCount(1);
- connect(ui->tableWidget, &QTableWidget::itemSelectionChanged, this, &MulticastPolicyWidget::jiemian);
-
-
- }
-
- MulticastPolicyWidget::~MulticastPolicyWidget()
- {
- delete ui;
- db_strategy.close();
- }
- //添加ID
- void MulticastPolicyWidget::on_pushButton_clicked()
- {
- bool ok;
- QString newText = QInputDialog::getText(this, "添加行", "输入新文本:", QLineEdit::Normal, NULL, &ok);
- QTableWidgetItem *item=new QTableWidgetItem(newText);
- if (ok) {
- int row = ui->tableWidget_2->rowCount();
- ui->tableWidget_2->insertRow(row);
- ui->tableWidget_2->setItem(row,0,item);
- }
-
- }
- //编辑ID
- void MulticastPolicyWidget::on_pushButton_2_clicked()
- {
- int currentRow = ui->tableWidget_2->currentRow();
- if (currentRow >= 0) {
- // 获取当前行的文本
- QString currentText = ui->tableWidget_2->item(currentRow, 0)->text();
-
- // 弹出输入对话框
- bool ok;
- QString newText = QInputDialog::getText(this, "修改行", "输入新文本:", QLineEdit::Normal, currentText, &ok);
-
- // 如果用户点击了 OK 按钮,则更新表格中的文本
- if (ok) {
- ui->tableWidget_2->item(currentRow, 0)->setText(newText);
- }
- }
- }
- //删除ID
- void MulticastPolicyWidget::on_pushButton_3_clicked()
- {
- int currentRow = ui->tableWidget_2->currentRow();
- if (currentRow >= 0) {
- ui->tableWidget_2->removeRow(currentRow);
- }
- }
- //添加策略
- void MulticastPolicyWidget::on_pushButton_4_clicked()
- {
- addDataToDatabase(createDataRecordFromUI());
-
-
- QVector<int> columnsToPrint;
- columnsToPrint << 0 << 1<<2<<3<<4;
- printTableDataToTableWidget("zuboguanli", ui->tableWidget, columnsToPrint);
- }
- //修改策略
- void MulticastPolicyWidget::on_pushButton_5_clicked()
- {
- updateDataInDatabase(createDataRecordFromUI());
- QVector<int> columnsToPrint;
- columnsToPrint << 0 << 1<<2<<3<<4; // 这里假设第1列和第3列需要打印
- printTableDataToTableWidget("zuboguanli", ui->tableWidget, columnsToPrint);
- }
- //删除策略
- void MulticastPolicyWidget::on_pushButton_6_clicked()
- {
- DataRecord rec=createDataRecordFromUI();
- deleteDataFromDatabase(rec.name);
- QVector<int> columnsToPrint;
- columnsToPrint << 0 << 1<<2<<3<<4; // 这里假设第1列和第3列需要打印
- printTableDataToTableWidget("zuboguanli", ui->tableWidget, columnsToPrint);
- }
-
-
- //数据库操作
- bool MulticastPolicyWidget::connectToDatabase()
- {
-
- // 初始化数据库连接
- db_strategy = QSqlDatabase::addDatabase("QSQLITE");
- db_strategy.setDatabaseName("strategy.db"); // 数据库文件的名称,替换为你想要的名称
-
- // 打开数据库连接
- if (!db_strategy.open()) {
- qDebug() << "Failed to open database:" << db_strategy.lastError().text();
- return 1;
- }
- deleteTableFromDatabase("zuboguanli");
- addTableToDatabase();
- // 创建表格并执行 SQL 语句来初始化数据库
-
-
- // 关闭数据库连接(如果需要的话)
- // db_strategy.close();
- }
- bool MulticastPolicyWidget::addTableToDatabase()
- {
- QSqlQuery query;
- query.exec("CREATE TABLE IF NOT EXISTS zuboguanli ("
- "name text primary key,"
- "dizhi TEXT,"
- "dongzuo TEXT,"
- "fengzhuang TEXT,"
- "suanfa TEXT,"
- "mudiid TEXT"
- ")");
-
- // 检查 SQL 查询是否执行成功
- if (query.lastError().isValid()) {
- qDebug() << "Database query error:" << query.lastError().text();
- return 1;
- }
- }
- //删除表
- bool MulticastPolicyWidget::deleteTableFromDatabase(const QString &tableName) {
- QSqlQuery query(db_strategy);
- QString deleteQuery = QString("DROP TABLE IF EXISTS %1").arg(tableName);
-
- if (query.exec(deleteQuery)) {
- qDebug() << "成功删除表:" << tableName;
- return true;
- } else {
- qDebug() << "删除表失败:" << query.lastError().text();
- return false;
- }
- }
-
- // 增加数据
- bool MulticastPolicyWidget::addDataToDatabase(const DataRecord &record) {
- QSqlQuery query(db_strategy);
- query.prepare("INSERT INTO zuboguanli (name, dizhi,dongzuo,fengzhuang,suanfa,mudiid) VALUES (?, ?, ?, ?, ?,?)");
- query.bindValue(0, record.name);
- query.bindValue(1, record.dizhi);
- query.bindValue(2, record.dongzuo);
- query.bindValue(3, record.fengzhuang);
- query.bindValue(4, record.suanfa);
- query.bindValue(5, record.mudiid);
-
-
- printDataRecord(record);
- if (query.exec()) {
- qDebug() << "成功插入数据";
- return true;
- } else {
- qDebug() << "插入数据失败:" << query.lastError().text();
- return false;
- }
-
- }
-
- // 删除数据
- bool MulticastPolicyWidget::deleteDataFromDatabase(const QString &name) {
- QSqlQuery query(db_strategy);
- query.prepare("DELETE FROM zuboguanli WHERE name = ?");
- query.bindValue(0, name);
-
- if (query.exec()) {
- qDebug() << "成功删除数据";
- return true;
- } else {
- qDebug() << "删除数据失败:" << query.lastError().text();
- return false;
- }
- }
-
- // 修改数据
- bool MulticastPolicyWidget::updateDataInDatabase(const DataRecord &record) {
- QSqlQuery query(db_strategy);
- query.prepare("UPDATE zuboguanli SET dizhi = ?, dongzuo = ?, fengzhuang = ?, suanfa = ?,mudiid=? WHERE name = ?");
- query.bindValue(0, record.dizhi);
- query.bindValue(1, record.dongzuo);
- query.bindValue(2, record.fengzhuang);
- query.bindValue(3, record.suanfa);
- query.bindValue(4, record.mudiid);
- query.bindValue(5, record.name);
-
- if (query.exec()) {
- qDebug() << "成功更新数据";
- return true;
- } else {
- qDebug() << "更新数据失败:" << query.lastError().text();
- return false;
- }
- }
-
- //点击查询数据
- DataRecord MulticastPolicyWidget::getDataRecordFromSelectedRow() {
- DataRecord record;
-
- // 获取选中的行号
- int selectedRow = ui->tableWidget->currentRow();
-
- // 检查是否有行被选中
- if (selectedRow < 0) {
- qDebug()<<"无选中行";
- return record;
- }
-
- // 提取选中行的标识数据,例如 name
- QString name = ui->tableWidget->item(selectedRow, 0)->text(); // 假设该列是 name
-
- // 执行数据库查询
- QSqlQuery query(db_strategy);
- query.prepare("SELECT * FROM zuboguanli WHERE name = ?");
- query.bindValue(0, name);
- if (query.exec() && query.first()) {
- // 从查询结果中提取数据并填充到 DataRecord 对象
- record.name = query.value("name").toString();
- record.dizhi = query.value("dizhi").toString();
- record.dongzuo = query.value("dongzuo").toString();
- record.fengzhuang = query.value("fengzhuang").toString();
- record.suanfa = query.value("suanfa").toString();
- record.mudiid = query.value("mudiid").toString();
- } else {
- qDebug() << "从数据库查询数据失败:" << query.lastError().text();
- }
-
- return record;
- }
-
- //数据库打印到表
- void MulticastPolicyWidget::printTableDataToTableWidget(const QString &tableName, QTableWidget *tableWidget, const QVector<int> &columnsToPrint) {
- // 清空表格中的数据
- tableWidget->setRowCount(0);
-
- // 执行查询获取指定表的所有数据
- QSqlQuery query;
- query.exec(QString("SELECT * FROM %1").arg(tableName));
-
- // 设置表格的列数
- if (query.isActive()) {
- int tableWidgetColumnCount = columnsToPrint.size();
-
- // 设置表格的列数(与入参中的列数相对应)
- tableWidget->setColumnCount(tableWidgetColumnCount);
- // 逐行填充数据
- int rowCount = 0;
- while (query.next()) {
- tableWidget->insertRow(rowCount);
- for (int i = 0; i < tableWidgetColumnCount; i++) {
- int col = columnsToPrint[i];
- tableWidget->setItem(rowCount, i, new QTableWidgetItem(query.value(col).toString()));
- }
- rowCount++;
- }
- } else {
- // 查询失败,可以在此处理错误
- }
- }
-
- //数据库转json
- QJsonDocument MulticastPolicyWidget::tableDataToJson(const QString &tableName) {
- // 创建一个 JSON 数组来存储表中的数据
- QJsonArray jsonArray;
-
- // 执行查询获取指定表的所有数据
- QSqlQuery query;
- query.exec(QString("SELECT * FROM %1").arg(tableName));
-
- // 将查询结果转换为 JSON 数组
- if (query.isActive()) {
- int columnCount = query.record().count();
- while (query.next()) {
- QJsonObject jsonObject;
- for (int col = 0; col < columnCount; col++) {
- QString columnName = query.record().fieldName(col);
- QVariant columnValue = query.value(col);
- jsonObject[columnName] = QJsonValue::fromVariant(columnValue);
- }
- jsonArray.append(jsonObject);
- }
- } else {
- // 查询失败,可以在此处理错误
- }
-
- // 创建一个 JSON 文档并返回
- QJsonDocument jsonDocument(jsonArray);
- return jsonDocument;
- }
-
- //json转数据库
-
- //获取界面文本
- DataRecord MulticastPolicyWidget::createDataRecordFromUI() {
-
- QString name = ui->lineEdit->text();
- QString dizhi = ui->lineEdit_2->text();
-
- if (name.isEmpty() || dizhi.isEmpty()) {
- // 如果 name 或 dizhi 为空,弹出警告
- QMessageBox::warning(this, "警告", "名称和地址不能为空!");
- } else if (name.length() > 15) {
- // 如果 name 长度超过15个字符,弹出警告
- QMessageBox::warning(this, "警告", "名称长度不能超过15个字符!");
- } else {
- // 检查 dizhi 格式是否合法
- QRegExp ipRegExp("(25[0-5]|2[0-4][0-9]|[0-1]?[0-9][0-9]?)\\."
- "(25[0-5]|2[0-4][0-9]|[0-1]?[0-9][0-9]?)\\."
- "(25[0-5]|2[0-4][0-9]|[0-1]?[0-9][0-9]?)\\."
- "(25[0-5]|2[0-4][0-9]|[0-1]?[0-9][0-9]?)");
- if (!ipRegExp.exactMatch(dizhi)) {
- // 如果 dizhi 不匹配 IP 地址格式,弹出警告
- QMessageBox::warning(this, "警告", "地址格式不合法,请输入有效的 IP 地址!");
- } else {
- // 执行其他操作,因为输入是有效的
- }
- }
- QString dongzuo = ui->comboBox->currentText();
- QString fengzhuang = ui->comboBox_2->currentText();
- QString suanfa = ui->comboBox_3->currentText();
- QString mudiid=tableWidgetToText(ui->tableWidget_2) ;
- DataRecord record(name, dizhi, dongzuo, fengzhuang, suanfa,mudiid);
- return record;
- }
-
- //设置界面文本
- void MulticastPolicyWidget::setDataRecordToUI(const DataRecord &record) {
- ui->lineEdit->setText(record.name);
- ui->lineEdit_2->setText(record.dizhi);
- ui->comboBox->setCurrentText(record.dongzuo);
- ui->comboBox_2->setCurrentText(record.fengzhuang);
- ui->comboBox_3->setCurrentText(record.suanfa);
- textToTableWidget(record.mudiid,ui->tableWidget_2);
- }
-
- //表格转文本
- QString MulticastPolicyWidget::tableWidgetToText(QTableWidget *tableWidget) {
- QString text;
-
- // 遍历每一行
- for (int row = 0; row < tableWidget->rowCount(); row++) {
- // 遍历每一列
- for (int col = 0; col < tableWidget->columnCount(); col++) {
- // 获取单元格的文本
- QTableWidgetItem *item = tableWidget->item(row, col);
- if (item) {
- text += item->text();
- }
- // 添加列之间的分隔符,例如制表符或逗号
- text += "\t"; // 在这里使用制表符分隔
- }
- // 添加行之间的分隔符,例如换行符
- text += "\n";
- }
-
- return text;
- }
- //文本转表格
- void MulticastPolicyWidget::textToTableWidget(const QString &text, QTableWidget *tableWidget) {
- // 清空表格
- tableWidget->clear();
- tableWidget->setRowCount(0);
- tableWidget->setColumnCount(0);
-
- QStringList lines = text.split('\n');
- int rowCount = lines.size();
-
- // 遍历每一行
- for (int row = 0; row < rowCount; row++) {
- // 移除行首和行尾的空白字符
- QString line = lines[row].trimmed();
- if (line.isEmpty()) {
- continue; // 如果行为空,跳过
- }
-
- // 分割每一行以获取列数据
- QStringList columns = line.split('\t'); // 使用制表符分隔
-
- // 如果列数与表格列数不匹配,添加新列
- if (tableWidget->columnCount() < columns.size()) {
- tableWidget->setColumnCount(columns.size());
- }
-
- // 添加新行
- tableWidget->insertRow(row);
-
- // 填充单元格数据
- for (int col = 0; col < columns.size(); col++) {
- QTableWidgetItem *item = new QTableWidgetItem(columns[col]);
- tableWidget->setItem(row, col, item);
- }
- }
- }
-
-
-
- void MulticastPolicyWidget::jiemian()
- {
- DataRecord rec=getDataRecordFromSelectedRow();
- setDataRecordToUI(rec);
- printDataRecord(rec);
- }
- void MulticastPolicyWidget::printDataRecord(const DataRecord &record) {
- qDebug() << "Name: " << record.name;
- qDebug() << "Dizhi: " << record.dizhi;
- qDebug() << "Dongzuo: " << record.dongzuo;
- qDebug() << "Fengzhuang: " << record.fengzhuang;
- qDebug() << "Suanfa: " << record.suanfa;
- qDebug() << "Mudiid: " << record.mudiid;
- }
-
- #ifndef MULTICASTPOLICYWIDGET_H
- #define MULTICASTPOLICYWIDGET_H
-
- #include
- #include
- namespace Ui {
- class MulticastPolicyWidget;
- }
-
-
- class DataRecord {
- public:
- DataRecord(const QString &name = QString(),
- const QString &dizhi = QString(),
- const QString &dongzuo = QString(),
- const QString &fengzhuang = QString(),
- const QString &suanfa = QString(),
- const QString &mudiid = QString())
- : name(name), dizhi(dizhi), dongzuo(dongzuo), fengzhuang(fengzhuang), suanfa(suanfa),mudiid(mudiid) {}
-
- QString name;
- QString dizhi;
- QString dongzuo;
- QString fengzhuang;
- QString suanfa;
- QString mudiid;
- };
-
-
- class MulticastPolicyWidget : public QWidget
- {
- Q_OBJECT
-
- public:
- explicit MulticastPolicyWidget(QWidget *parent = nullptr);
- ~MulticastPolicyWidget();
- bool connectToDatabase();
- bool addDataToDatabase(const DataRecord &record);
- bool deleteDataFromDatabase(const QString &name);
- bool updateDataInDatabase(const DataRecord &record);
- void printTableDataToTableWidget(const QString &tableName, QTableWidget *tableWidget, const QVector<int> &columnsToPrint);
- QJsonDocument tableDataToJson(const QString &tableName);
- DataRecord createDataRecordFromUI();
- QString tableWidgetToText(QTableWidget *tableWidget);
- void textToTableWidget(const QString &text, QTableWidget *tableWidget);
- void setDataRecordToUI(const DataRecord &record);
- DataRecord getDataRecordFromSelectedRow();
- void jiemian();
- bool deleteTableFromDatabase(const QString &tableName);
- void printDataRecord(const DataRecord &record);
- bool addTableToDatabase();
- private slots:
- void on_pushButton_clicked();
-
- void on_pushButton_2_clicked();
-
- void on_pushButton_3_clicked();
-
- void on_pushButton_4_clicked();
-
- void on_pushButton_5_clicked();
-
- void on_pushButton_6_clicked();
-
- private:
- Ui::MulticastPolicyWidget *ui;
- };
-
- #endif // MULTICASTPOLICYWIDGET_H
进度条平滑效果
- 要实现平滑地将 `QProgressBar` 滑块拉到最大值,你可以使用 `QPropertyAnimation` 类。这将允许你在一段时间内逐渐增加 `QProgressBar` 的值,从而实现平滑的效果。下面是如何使用 `QPropertyAnimation` 来实现这一点:
-
- 首先,确保你在 `.pro` 文件中添加了 `widgets` 模块:
-
- ```qmake
- QT += widgets
- ```
-
- 然后,使用以下代码实现平滑的效果:
-
- ```cpp
-
- // 创建 QPropertyAnimation 对象
- QPropertyAnimation *animation = new QPropertyAnimation(ui->progressBar, "value");
-
- // 设置动画参数
- animation->setDuration(2000); // 2秒
- animation->setStartValue(ui->progressBar->value());
- animation->setEndValue(ui->progressBar->maximum());
-
- // 开始动画
- animation->start();
-
- ```
-
- 这段代码将创建一个 `QPropertyAnimation` 对象,将 `value` 属性从当前值逐渐增加到最大值,这样你就可以实现平滑的进度条动画效果。
信号与槽
- connect(m_syswidget,SIGNAL(Applicationquit()),this,SLOT(Exit()));
-
- connect(m_syswidget,&SystemManageWidget::Applicationquit,qApp,&QApplication::quit);
时间添加1s
dateTime = dateTime.addSecs(1); // 添加一秒
设计方法
- 如果你希望简化使用的通用函数,可以创建一个模板函数,它可以接受任何类型的数据,如下所示:
-
- ```cpp
- #include
- #include
-
- template <typename T>
- void handleResult(const QJsonObject &recv, const T &key, std::function<void()> onSuccess, std::function<void()> onFailure) {
- if (recv.contains(key)) {
- if (recv[key].toBool()) {
- onSuccess(); // 调用成功操作函数
- } else {
- onFailure(); // 调用失败操作函数
- }
- }
- }
-
- // 使用示例
- handleResult(recv1, "SetTime",
- []() {
- // 操作函数1
- },
- []() {
- // 操作函数2
- }
- );
-
- handleResult(recv1, "AnotherKey",
- []() {
- // 操作函数3
- },
- []() {
- // 操作函数4
- }
- );
- ```
-
- 这个通用函数现在可以接受一个键(key)和你希望检查的 QJsonObject,以及两个操作函数。这样,你可以根据需要简单地调用通用函数来处理不同的 JSON 数据和操作函数。
更好的设计方法
- 如果你希望 `handleResult` 函数支持具有不同参数的 `onSuccess` 和 `onFailure` 函数,可以使用 C++ 的模板来实现。以下是修改后的函数:
-
- ```cpp
- template <typename T, typename FuncSuccess, typename FuncFailure>
- void SystemManageWidget::handleResult(const QJsonObject &recv, const T &key, FuncSuccess onSuccess, FuncFailure onFailure) {
- if (recv.contains(key)) {
- if (recv[key].toBool()) {
- onSuccess(); // 调用成功操作函数
- } else {
- onFailure(); // 调用失败操作函数
- }
- }
- }
- ```
-
- 在这个版本中, `handleResult` 接受两个函数对象 `onSuccess` 和 `onFailure`,它们可以带有任意数量的参数。你可以像这样使用它:
-
- ```cpp
- handleResult(recv, "SetTime", [this]() {
- // 成功操作函数,可以带有任意参数
- showMessage("操作成功", "设置时间操作成功!");
- }, [this]() {
- // 失败操作函数,可以带有任意参数
- showMessage("操作成功", "设置时间操作失败!");
- });
- ```
- 在 lambda 函数中没有捕获 this 指针,无法使用类的成员函数
-
- 通过这种方式,你可以根据具体需要定义成功和失败操作函数,并将它们传递给 `handleResult`,而不受参数数量的限制。
请设计一个函数事界面失能,并记时三秒,若三秒后仍然失能,则使界面使能
- 你可以使用 Qt 的 `QTimer` 类来实现这个功能。以下是一个设计函数的示例,该函数将界面禁用,然后在三秒后重新启用:
-
- ```cpp
- #include
-
- // 在你的类中定义一个 QTimer 成员变量
- QTimer *disableTimer;
-
- // 在你的构造函数中初始化 QTimer
- YourConstructor::YourConstructor() {
- disableTimer = new QTimer(this);
- disableTimer->setSingleShot(true);
- connect(disableTimer, &QTimer::timeout, this, &YourClass::enableUI); // 在超时后启用界面
- }
-
- // 编写一个函数来禁用界面并启动计时器
- void YourClass::disableUI() {
- // 禁用你的界面元素,例如:ui->pushButton->setEnabled(false);
- // 启动计时器,三秒后触发 timeout 信号
- this->setEnabled(false);
- disableTimer->start(3000); // 3000 毫秒(3秒)
- }
-
- // 编写一个函数在计时器超时后启用界面
- void YourClass::enableUI() {
- if(!this->isEnabled())
- {
- ///
- }
- // 启用你的界面元素,例如:ui->pushButton->setEnabled(true);
- this->setEnabled(true);
- }
- ```
-
- 上述代码首先初始化了一个单次触发的 `QTimer`,并连接了 `timeout` 信号到 `enableUI` 槽函数。`disableUI` 函数在需要禁用界面时调用,它会禁用界面元素,然后启动计时器。当计时器超时后(三秒后),`timeout` 信号触发,执行 `enableUI` 槽函数,这时可以重新启用界面元素。
-
- 请注意,你需要适应代码以符合你的具体界面和需求。
上一个问题更简洁的方法
- 你可以简化你的代码,如下所示:
-
- ```cpp
- disableTimer = new QTimer(this);
- disableTimer->setSingleShot(true);
- connect(disableTimer, &QTimer::timeout, this, &SystemManageWidget::enableUI); // 在超时后启用界面
-
- void SystemManageWidget::disableUI()
- {
- setEnabled(false);
- disableTimer->start(5000); // 5000 毫秒(5秒)
- }
-
- void SystemManageWidget::enableUI()
- {
- if (!isEnabled())
- showMessage("请求超时");
- setEnabled(true);
- }
- ```
-
- 这个简化的代码与之前的代码功能相同,但通过删除冗余的`this->`和将`setEnabled`直接应用于对象,使代码更加简洁。
通用弹窗
- 你可以创建一个通用的函数来简化这个弹出窗口的创建和处理。以下是一个示例函数,用于创建通用的消息框:
-
- ```cpp
- #include
- #include
-
- int showCustomMessageBox(const QString &title, const QString &text,
- const QString &confirmButtonText, const QString &cancelButtonText,
- QMessageBox::Icon icon = QMessageBox::Information, QWidget *parent = nullptr)
- {
- QMessageBox messageBox(icon, title, text, QMessageBox::Ok | QMessageBox::Cancel, parent);
- messageBox.setButtonText(QMessageBox::Ok, confirmButtonText);
- messageBox.setButtonText(QMessageBox::Cancel, cancelButtonText);
-
- int choice = messageBox.exec();
- return choice;
- }
- ```
-
- 你可以将这个函数添加到你的代码中,然后在需要显示消息框的地方调用它。例如:
-
- ```cpp
- int choice = showCustomMessageBox("密码机管理器", "恢复设置成功,是否退出管理器", "确认", "取消", QMessageBox::Warning);
-
- if (choice == QMessageBox::Ok)
- {
- // 用户点击确认按钮的处理逻辑
- emit a();
- }
- else if (choice == QMessageBox::Cancel)
- {
- // 用户点击取消按钮的处理逻辑
- emit b();
- }
- ```
-
- 这个函数接受标题、文本、确认按钮文本、取消按钮文本和图标作为参数,并返回用户的选择,使你可以更容易地创建和处理通用的消息框。
设计方法使用问题
- template <typename T, typename FuncSuccess, typename FuncFailure>
- void SystemManageWidget::handleResult(const QJsonObject &recv, const T &key, FuncSuccess onSuccess, FuncFailure onFailure) {
-
- this->setEnabled(true);
- if (recv.contains(key)) {
- if (recv[key].toBool()) {
- onSuccess(); // 调用成功操作函数
- } else {
- onFailure(); // 调用失败操作函数
- }
- }
- }
- handleResult(recv, "SetTime",&SystemManageWidget::showMessage( "设置时间操作成功!") ,&SystemManageWidget:: showMessage( "设置时间操作失败!") );
- error: cannot take the address of an rvalue of type 'void'
- 为什么不对
-
-
-
- 问题出在你试图传递成员函数 `SystemManageWidget::showMessage` 作为参数。成员函数需要与特定的实例关联,所以不能直接传递给一个通用函数。
-
- 为了解决这个问题,你可以使用 `std::function` 来包装成员函数并传递它们。下面是如何修改 `handleResult` 函数的方式:
-
- ```cpp
- template <typename T, typename FuncSuccess, typename FuncFailure>
- void SystemManageWidget::handleResult(const QJsonObject &recv, const T &key, FuncSuccess onSuccess, FuncFailure onFailure) {
- this->setEnabled(true);
- if (recv.contains(key)) {
- if (recv[key].toBool()) {
- onSuccess(); // 调用成功操作函数
- } else {
- onFailure(); // 调用失败操作函数
- }
- }
- }
-
- // 示例调用
- handleResult(recv, "SetTime",
- [this]() { showMessage("设置时间操作成功!"); },
- [this]() { showMessage("设置时间操作失败!"); }
- );
- ```
-
- 在示例调用中,使用了 lambda 函数来包装成员函数调用,以确保它们与当前的 `SystemManageWidget` 实例相关联。
将多个数据封装成1个数据的方法
- 将多个数据封装成一个数据的好方法是使用结构(struct)或类(class),这取决于编程语言和需求。以下是一些方法:
-
- 1. **结构(Struct)**:
- - 结构是一种轻量级的数据类型,通常用于封装一组相关的数据字段。
- - 结构的成员变量可以是不同的数据类型,例如整数、字符串、浮点数等。
- - 适用于小型数据对象,不需要复杂的方法或成员函数。
-
- 示例(C++):
- ```cpp
- struct Person {
- std::string name;
- int age;
- double height;
- };
- ```
-
- 2. **类(Class)**:
- - 类是一种更强大的数据类型,允许封装数据字段和相关的操作方法(成员函数)。
- - 类的成员函数可以用于操作封装的数据,提供了更多的控制和封装性。
- - 适用于需要处理复杂对象,包括数据和行为的情况。
-
- 示例(C++):
- ```cpp
- class Person {
- private:
- std::string name;
- int age;
- double height;
-
- public:
- Person(const std::string &n, int a, double h) : name(n), age(a), height(h) {}
-
- void setName(const std::string &n) { name = n; }
- void setAge(int a) { age = a; }
- void setHeight(double h) { height = h; }
- std::string getName() const { return name; }
- int getAge() const { return age; }
- double getHeight() const { return height; }
- };
- ```
-
- 3. **字典(Dictionary)或映射(Map)**:
- - 如果你需要将一组数据关联到特定的键,可以使用字典或映射数据结构。
- - 这允许你通过键查找和访问相关的数据。
-
- 示例(Python):
- ```python
- person = {
- "name": "John",
- "age": 30,
- "height": 175.5
- }
- ```
-
- 4. **元组(Tuple)**:
- - 元组是一种不可变的数据结构,用于组合多个数据项。
- - 适用于不需要修改封装数据的情况。
-
- 示例(Python):
- ```python
- person = ("John", 30, 175.5)
- ```
-
- 5. **JSON或XML**:
- - 如果需要在多个应用程序或平台之间传递数据,可以使用JSON或XML格式来封装和序列化数据。
-
- 示例(JSON):
- ```json
- {
- "name": "John",
- "age": 30,
- "height": 175.5
- }
- ```
-
- 选择哪种方法取决于你的具体需求,例如数据大小、复杂性、是否需要操作方法等。不同的编程语言也提供了不同的工具和数据结构来实现数据封装。
QT中将多个数据封装成1个数据的方法
- 在Qt中,你可以使用类(class)或结构体(struct)来将多个数据封装成一个数据。这通常依赖于你的需求和数据的性质。以下是一些方法:
-
- 1. **使用类(class)**:
- - 在Qt中,你可以创建一个自定义类,将多个数据成员存储在这个类中。
- - 使用类的优点是可以添加成员函数来执行操作和维护数据的封装性。
- - 这对于需要更多行为的数据对象非常有用。
-
- 示例(C++,Qt):
- ```cpp
- class Person {
- public:
- Person(const QString &name, int age, const QDate &birthDate)
- : m_name(name), m_age(age), m_birthDate(birthDate) {
- }
-
- QString name() const { return m_name; }
- int age() const { return m_age; }
- QDate birthDate() const { return m_birthDate; }
-
- private:
- QString m_name;
- int m_age;
- QDate m_birthDate;
- };
- ```
-
- 2. **使用结构体(struct)**:
- - 结构体是另一种用于封装数据的方式,它通常更轻量。
- - 结构体的成员可以是不同的数据类型,但没有成员函数。
- - 这适用于小型数据对象,不需要操作。
-
- 示例(C++,Qt):
- ```cpp
- struct Person {
- QString name;
- int age;
- QDate birthDate;
- };
- ```
-
- 3. **使用QVariantMap**:
- - Qt提供了QVariantMap作为一种通用数据容器,可以用于存储多个不同类型的数据。
- - 这对于将多个数据打包到一个对象中非常有用,而不需要定义自定义类。
- - 注意,QVariantMap需要手动处理数据类型的转换。
-
- 示例(C++,Qt):
- ```cpp
- QVariantMap personData;
- personData["name"] = "John";
- personData["age"] = 30;
- personData["birthDate"] = QDate(1992, 5, 15);
- ```
-
- 选择哪种方法取决于你的具体需求和项目的规模。如果需要更多的控制和操作,使用类可能更合适。如果只需存储和检索数据,结构体或QVariantMap可能足够。
-
- 4. **使用QPair和QMap**:
- - 如果你只需要将两个值配对,可以使用QPair。
- - 如果你有多个字段需要存储,可以使用QMap,其中键是字段名,值是字段值。
-
- 示例(QPair,C++,Qt):
- ```cpp
- QPair
int > personData("John", 30); - ```
-
- 示例(QMap,C++,Qt):
- ```cpp
- QMap
personData; - personData["name"] = "John";
- personData["age"] = 30;
- ```
-
- 5. **使用自定义数据结构**:
- - 你还可以自定义一个数据结构,不必使用Qt提供的类或结构体。
- - 这样可以更好地满足特定需求,例如使用数组、列表或其他数据容器。
-
- 示例(C++,Qt):
- ```cpp
- struct CustomData {
- QString name;
- int age;
- QDate birthDate;
- QVector<int> scores;
- };
- ```
-
- 6. **使用元组(Tuple)**:
- - C++11引入了元组,可以用来包装多个数据项。
- - 使用`std::tuple`可以创建具有不同数据类型的元组。
-
- 示例(C++11):
- ```cpp
- std::tuple
int , QDate> personData("John", 30, QDate(1992, 5, 15)); - ```
-
- 上述方法中的每一种都有不同的优缺点,根据你的具体需求来选择最合适的方法。如果只需要简单地存储和检索数据,QVariantMap可能是一个不错的选择。如果需要更多的操作或具有复杂的数据结构,自定义类可能更合适。
TCP UDP的基类
-
- #include
- #include
- #include
-
- class NetworkProtocolBase : public QObject
- {
- Q_OBJECT
-
- public:
- NetworkProtocolBase(QObject* parent = nullptr) : QObject(parent) {}
-
- // 公共接口用于连接和断开连接
- virtual bool connectToHost(const QString& host, quint16 port) = 0;
- virtual void disconnect() = 0;
-
- // 发送数据
- virtual qint64 send(const QByteArray& data) = 0;
-
- signals:
- // 接收到数据时发射的信号
- void dataReceived(const QByteArray& data);
-
- // 连接建立时发射的信号
- void connected();
-
- // 连接断开时发射的信号
- void disconnected();
-
- protected slots:
- // 接收数据的槽
- virtual void receiveData() = 0;
- };
tabWidget当不是第一个页面时,发出信号,当回到第一个信号时发出信号.
- int previousTabIndex = 0; // 用于存储上一个选项卡的索引
-
- connect(tabWidget, &QTabWidget::currentChanged, this, &YourClass::onTabChanged);
-
- void YourClass::onTabChanged(int currentTabIndex)
- {
- if (currentTabIndex == 0 && previousTabIndex != 0) {
- // 当切换回第一个选项卡时发出信号
- emit returnedToFirstTab();
- } else if (currentTabIndex != 0 && previousTabIndex == 0) {
- // 当从第一个选项卡切换到其他选项卡时发出信号
- emit switchedFromFirstTab();
- }
-
- // 更新上一个选项卡的索引
- previousTabIndex = currentTabIndex;
- }
tabWidget当不是第一个页面时,返回false,当回到第一个信号时返回true.
- connect(tabWidget, &QTabWidget::currentChanged, this, [this](int currentTabIndex) {
- TIME = (currentTabIndex == 0);
- });
stackedWidget当不是第一个页面时,发出信号,当回到第一个信号时发出信号
- int previousPageIndex = 0; // 用于存储上一个页面的索引
-
- connect(stackedWidget, &QStackedWidget::currentChanged, this, [this](int currentPageIndex) {
- if (currentPageIndex == 0) {
- // 当切换回第一个页面时发出信号
- emit returnedToFirstPage();
- } else if (previousPageIndex == 0) {
- // 当从第一个页面切换到其他页面时发出信号
- emit switchedFromFirstPage();
- }
-
- // 更新上一个页面的索引
- previousPageIndex = currentPageIndex;
- });
stackedWidget当不是第一个页面时,返回false,当回到第一个信号时返回true.
- connect(stackedWidget, &QStackedWidget::currentChanged, this, [this](int currentPageIndex) {
- TIME = (currentPageIndex == 0);
- });
读取文件
- #include
- #include
- #include
- #include
- #include
-
- QString readTextFile(const QString &filePath) {
- QString fileContents;
-
- // 创建 QFile 对象并尝试打开文件
- QFile file(filePath);
- if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
- QTextStream in(&file);
- fileContents = in.readAll();
- file.close();
- } else {
-
- qDebug() << "无法打开文件:" << filePath;
- }
-
- return fileContents;
- }
实时检测脚本文件的输出
- 如果你不需要继承自`QThread`的类,而只是想在主线程中使用`QProcess`运行脚本,可以直接使用`QProcess`和信号槽来实现。以下是相应的修改后的代码:
-
- ```cpp
- #include
- #include
- #include
-
- class ScriptRunner : public QObject
- {
- Q_OBJECT
-
- public:
- ScriptRunner(const QString& scriptPath, const QStringList& arguments) :
- scriptPath(scriptPath), arguments(arguments), processRunning(false)
- {
- // 初始化 QProcess
- process.setProgram(scriptPath);
- process.setArguments(arguments);
-
- // 连接进程的readyReadStandardOutput信号到槽函数
- connect(&process, &QProcess::readyReadStandardOutput, this, [=]() {
- // 读取进程输出
- QByteArray output = process.readAllStandardOutput();
- qDebug() << "脚本输出:" << output;
-
- // 发出输出信号
- emit scriptOutput(output);
- });
-
- // 连接进程的finished信号到槽函数
- connect(&process, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), this, [=](int exitCode, QProcess::ExitStatus exitStatus) {
- qDebug() << "进程退出码:" << exitCode;
- // 发出脚本运行结束信号
- emit scriptFinished(exitCode);
- processRunning = false;
- });
- }
-
- // 启动进程
- void startProcess()
- {
- if (!processRunning) {
- // 启动进程
- process.start();
- processRunning = true;
- }
- }
-
- // 关闭进程
- void stopProcess()
- {
- if (processRunning) {
- // 关闭进程
- process.kill();
- process.waitForFinished(-1);
- processRunning = false;
- }
- }
-
- public slots:
- // 向正在运行的进程发送指令
- void sendCommand(const QString& command)
- {
- if (processRunning) {
- // 向进程写入指令
- process.write(command.toUtf8());
- process.waitForBytesWritten();
- }
- }
-
- signals:
- // 发出输出信号
- void scriptOutput(const QByteArray& output);
-
- // 发出脚本运行结束信号
- void scriptFinished(int exitCode);
-
- private:
- QString scriptPath; // 脚本路径
- QStringList arguments; // 脚本参数
- QProcess process; // 外部进程
- bool processRunning; // 进程是否在运行
- };
-
- int main(int argc, char *argv[])
- {
- QCoreApplication a(argc, argv);
-
- // 创建 ScriptRunner 对象
- ScriptRunner scriptRunner("/path/to/your_acv_executable", {"arg1", "arg2", "arg3"});
-
- // 连接 ScriptRunner 的输出信号到槽函数
- QObject::connect(&scriptRunner, &ScriptRunner::scriptOutput, [](const QByteArray& output) {
- qDebug() << "Received Output:" << output;
- // 处理输出,例如显示在界面上
-
- // 在接收到数据后,向正在运行的进程发送指令
- scriptRunner.sendCommand("your_command_here");
- });
-
- // 连接 ScriptRunner 的脚本运行结束信号到槽函数
- QObject::connect(&scriptRunner, &ScriptRunner::scriptFinished, [&](int exitCode) {
- qDebug() << "Script Finished with Exit Code:" << exitCode;
- // 处理脚本运行结束
- a.quit(); // 结束应用程序事件循环
- });
-
- // 启动 ScriptRunner
- scriptRunner.startProcess();
-
- // 进入主线程的事件循环
- return a.exec();
- }
- ```
-
- 这个版本的代码使用了主线程,而不是继承自`QThread`的自定义线程类。
你是一个精通设计模式的老程序员,请设计一个QT类,他的作用是创建一个QProcess,并至少有下面的函数“启动QProcess”,“监听接收来自QProcess的消息并发出信号”,“向QProcess发送消息”,“关闭QProcess”
当设计一个包含启动、监听、发送消息和关闭功能的QProcess管理类时,你可以创建一个自定义的类,例如 ProcessManager。下面是一个简单的实现:
- // processmanager.h
- #ifndef PROCESSMANAGER_H
- #define PROCESSMANAGER_H
-
- #include
- #include
-
- class ProcessManager : public QObject
- {
- Q_OBJECT
-
- public:
- explicit ProcessManager(QObject *parent = nullptr);
- ~ProcessManager();
-
- // 启动QProcess
- void startProcess(const QString &program, const QStringList &arguments = QStringList());
-
- signals:
- // 信号:接收来自QProcess的消息
- void processMessageReceived(const QString &message);
-
- public slots:
- // 向QProcess发送消息
- void sendMessageToProcess(const QString &message);
-
- // 关闭QProcess
- void closeProcess();
-
- private slots:
- // 处理QProcess的输出
- void processReadyRead();
-
- private:
- QProcess *process;
- };
-
- #endif // PROCESSMANAGER_H
- // processmanager.cpp
- #include "processmanager.h"
-
- ProcessManager::ProcessManager(QObject *parent)
- : QObject(parent)
- {
- // 初始化 QProcess 对象
- process = new QProcess(this);
-
- // 连接信号槽,处理 QProcess 的输出
- connect(process, &QProcess::readyReadStandardOutput, this, &ProcessManager::processReadyRead);
- }
-
- ProcessManager::~ProcessManager()
- {
- // 在析构函数中关闭 QProcess
- closeProcess();
- }
-
- void ProcessManager::startProcess(const QString &program, const QStringList &arguments)
- {
- // 启动 QProcess
- process->start(program, arguments);
- }
-
- void ProcessManager::sendMessageToProcess(const QString &message)
- {
- // 向 QProcess 发送消息
- if (process->state() == QProcess::Running)
- process->write(message.toUtf8());
- }
-
- void ProcessManager::closeProcess()
- {
- // 关闭 QProcess
- if (process->state() == QProcess::Running)
- process->terminate();
- }
-
- void ProcessManager::processReadyRead()
- {
- // 读取 QProcess 的输出,并发出信号
- QString output = QString::fromUtf8(process->readAllStandardOutput());
- emit processMessageReceived(output);
- }
这个类中包含了启动、监听、发送消息和关闭 QProcess 的功能。你可以在你的应用程序中实例化 ProcessManager 类,然后连接 processMessageReceived 信号来接收来自 QProcess 的消息。使用 sendMessageToProcess 函数可以向 QProcess 发送消息,而 closeProcess 函数用于关闭 QProcess。
延时函数
- void Delay_MSec(unsigned int msec)
- {
- QEventLoop loop;//定义一个新的事件循环
- QTimer::singleShot(msec, &loop, SLOT(quit())); //创建单次定时器,槽函数为事件循环的退出函数
- loop.exec(); //事件循环开始执行,程序会卡在这里,直到定时时间到,本循环被退出
- }
-
相关阅读:
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