按钮按下三秒禁用
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<QWidget*>()) {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); // 设置第二列的单元格为数据
}
UDP通信
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地址转换为QHostAddressQHostAddress 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;}
}
样式表使用方法
在项目文件创建一个文件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); // 第八列索引为7bool 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 <QCoreApplication>
#include <QTimer>
#include <QEventLoop>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();
}