电商网站开发要多少钱,尔雅网站开发实战,网站备案的要求是什么情况,淮南政务个人主页~ Qt系统内容 一、Qt文件1、文件读写读写 2、文件和目录信息 二、多线程1、线程使用timethread.hwidget.htimethread.cppwidget.cpp 2、线程安全#xff08;1#xff09;互斥锁QMutexQMutexLocker一个例子mythread.hmythread.cppwidget.cpp QReadWriteLocker、QReadL… 个人主页~ Qt系统内容 一、Qt文件1、文件读写读写 2、文件和目录信息 二、多线程1、线程使用timethread.hwidget.htimethread.cppwidget.cpp 2、线程安全1互斥锁QMutexQMutexLocker一个例子mythread.hmythread.cppwidget.cpp QReadWriteLocker、QReadLocker、QWriteLocker 2条件变量3信号量 一、Qt文件
对于Qt文件QFile的相关关系都在下面这个思维导图里面了它的父类是QFileDevice爷爷类是QIODeviceQt中所有的输入输出的类都是继承自QIODevice其中也包括网络IO、串口IO、蓝牙IO等 1、文件读写
对于文件的操作主要有读数据、写数据、关闭文件
操作说明QIODevice::NotOpen没有打开设备QIODevice::ReadOnly以只读方式打开设备QIODevice::WriteOnly以只写方式打开设备QIODevice::ReadWrite以读写方式打开设备QIODevice::Append以追加方式打开设备数据将写到文件末尾QIODevice::Truncate每次打开文件后重写文件内容原内容将被删除QIODevice::Text在读⽂件时行尾终止符会被转换为’\n’当写入⽂件时行尾终止符会被转换为本地编码如Win32上为’\r\n’QIODevice::Unbuffered无缓冲形式打开文件绕过设备中的任何缓冲区QIODevice::NewOnly文件存在则打开失败不存在则创建文件
读
Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui-setupUi(this);connect(ui-pushButton,QPushButton::clicked,[](){//获得文件路径QString path QFileDialog::getOpenFileName(this,打开文件,C:\\Users\\14725\\Desktop);//将路径设置为lineEdit的内容ui-lineEdit-setText(path);//通过path路径打开文件QFile file(path);//以只读方式打开文件file.open(QIODevice::ReadOnly);//读取所有的内容存在str字符串中QString str file.readAll();//将字符串放到textEdit中ui-textEdit-setText(str);file.close();});
}qfile 写
Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui-setupUi(this);connect(ui-pushButton,QPushButton::clicked,[](){QString path QFileDialog::getOpenFileName(this,打开文件,C:\\Users\\14725\\Desktop);ui-lineEdit-setText(path);QFile file(path);//以写方式打开文件file.open(QIODevice::Append);//写入的内容file.write(写进去的字);file.close();});
}qfile_2 2、文件和目录信息
方法说明isDir检查是否是目录isExecutable检查是否是可执行文件fileName获得文件名completeBaseName获取完整的文件名suffix获取文件后缀completeSuffix获取完整文件后缀size获取文件大小isFile判断是否为文件fileTime获取文件的创建时间、修改时间、最近访问时间等
Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui-setupUi(this);QString path QFileDialog::getOpenFileName(this,打开文件,C:\\Users\\14725\\Desktop);QFileInfo fileinfo(path);//这里的.toUtf8().data()后缀主要为为了将字符串转化为C字符串不加时输出为阿门.txt//加上输出为阿门.txt会去掉引号qDebug() 文件名 fileinfo.fileName().toUtf8().data();qDebug() 后缀名 fileinfo.suffix().toUtf8().data();qDebug() 文件大小 fileinfo.size();qDebug() 文件路径 fileinfo.path().toUtf8().data();qDebug() 是否为文件 fileinfo.isFile();qDebug() 是否为目录 fileinfo.isDir();QDateTime time1 fileinfo.fileTime(QFileDevice::FileBirthTime);qDebug() 创建时间 time1.toString(yyyy-MM-dd hh:mm:ss).toUtf8().data();QDateTime time2 fileinfo.lastModified();qDebug() 上次修改时间 time2.toString(yyyy-MM-dd hh:mm:ss).toUtf8().data();
}文件属性 程序输出
二、多线程
1、线程使用
在Qt中多线程的处理一般是通过QTread类来控制实现的这部分的内容与Linux内容强相关我在学习这一块的时候是没有学习过Linux的所以我是通过0Linux的基础来写下这部分内容的
API说明run线程入口函数start通过调用run开始执行线程操作系统根据优先级判定如果线程正在运行则这个函数相当于没有currentTread返回一个指向管理当前执行线程的QTread指针isRunning判断线程是否正在运行sleep使程序休眠单位为s类似的函数msleep单位为msusleep单位为uswait阻塞线程与此QTread对象关联的线程已经完成执行或者尚未启动都返回true如果等待超时返回falseterminate终止线程执行通过操作系统的调度决定是否立即终止finished线程结束后发出该信号
创建一个自定义类timethread继承自QThread在ui上创建一个pushbutton和label
timethread.h
class TimeThread : public QThread
{Q_OBJECT;
public:TimeThread();//线程任务函数void run();
signals://声明信号函数void sendTime(QString Time);
};widget.h
class Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent nullptr);~Widget();
private slots:void showTime(QString Time);void on_pushButton_clicked();private:Ui::Widget *ui;//定义线程对象TimeThread t;
};timethread.cpp
void TimeThread::run()
{while (1) {QString time QTime::currentTime().toString(hh::mm::ss);//发送信号emit sendTime(time);sleep(1);//每一秒发送一次信号}
}widget.cpp
Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui-setupUi(this);//当t每次sendTime的时候触发showTimeconnect(t,TimeThread::sendTime,this,Widget::showTime);
}Widget::~Widget()
{delete ui;
}void Widget::showTime(QString Time)
{//设置label的内容为时间ui-label-setText(Time);
}void Widget::on_pushButton_clicked()
{//开启线程t.start();
}QTread 我们前面也说过线程函数内部不允许操作ui图形界面一般是用作数据处理的 connect函数有五个参数第五个参数就是只有在多线程的时候才有意义用于指定信号和槽的连接类型同时影响信号的传递方式和槽函数的执行顺序
参数说明Qt::AutoConnection根据信号和槽函数所在的线程自动选择连接类型同一线程使用Qt::DirectConnection不同线程使用Qt::UniqueConnectionQt::DirectConnection信号发出时槽函数会立即在同一线程中执行适用于信号和槽在同一线程时Qt::QueuedConnection信号发出时槽函数会被插入到接收对象所属的线程的事件队列中等待下一次时间循环时执行适用于信号和槽不在同一线程Qt::BlockingQueuedConnection信号发出时发送信号的线程会被阻塞直到槽函数执行完毕适用于信号和槽不在同一线程Qt::UniqueConnection确保信号与槽之间唯一连接关系的标志可以使用位或操作与上述四种一种连接类型组合使用可以避免重复连接
2、线程安全
1互斥锁
互斥锁是一种保护和防止多个线程同时访问同一对象实例的办法主要通过QMutex类来处理
QMutex
用于保护共享资源的访问实现线程间的互斥操作在多线程的环境下通过互斥锁来控制对共享数据的访问确保线程安全
QMutex mutex;
mutex.lock();//上锁//访问共享资源mutex.unlock();//解锁QMutexLocker
可以简化对互斥锁的上锁解锁操作避免忘记解锁导致死锁
QMutex mutex;
{QMutexLocker locker(mutex);//作用域内自动上锁//访问共享资源...}//作用域结束自动解锁一个例子
mythread.h
class MyThread : public QThread
{
public:MyThread(QObject* parent nullptr);void run();private://定义全局变量static QMutex mutex;static int num;
};mythread.cpp
void MyThread::run()
{while (1) {this-mutex.lock();//锁上//每有一个线程进来就打印线程以及递增的数字qDebug() this : this-num;this-mutex.unlock();//解锁QThread::sleep(1);}
}在这个代码块中mutex.lock() 和 mutex.unlock() 手动管理互斥锁每次打印完信息后立即释放锁然后进行 QThread::sleep(1)由于锁已经释放其他线程可以立即进入这段代码导致线程的执行和打印信息可能是无序的
void MyThread::run()
{while (1) {QMutexLocker locker(mutex);qDebug() this : this-num;QThread::sleep(1);}
}在这个代码块中使用了 QMutexLocker 来管理锁QMutexLocker 会在它的作用范围内自动锁定 mutex并在 locker 离开作用域时即循环的下一次迭代开始时自动解锁在这里QThread::sleep(1) 位于锁的作用范围内所以整个 sleep 期间锁不会释放这样可以保证一次只有一个线程在运行这段代码从而避免线程间的竞争
widget.cpp
Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui-setupUi(this);MyThread* t1 new MyThread(this);MyThread* t2 new MyThread(this);t1-start();t2-start();
}QReadWriteLocker、QReadLocker、QWriteLocker
QReadWriteLocker读写锁类用于控制读和写的并发访问 QReadLocker读操作上锁允许多个线程同时读取共享资源 QWriteLocker写操作上锁只允许一个线程写入共享资源
QReadWriteLock rwLock;//在读操作中使⽤读锁
{QReadLocker locker(rwLock); //在作⽤域内⾃动上读锁//读取共享资源//...
}//在作⽤域结束时⾃动解读锁//在写操作中使⽤写锁
{QWriteLocker locker(rwLock); //在作⽤域内⾃动上写锁//修改共享资源//...
}//在作⽤域结束时⾃动解写锁
2条件变量
因为在多线程编程中某些线程需要等待某些条件满足才能执行此时线程会使用锁的机制来阻塞其他线程当条件满足时等待条件的线程将被另一个线程唤醒
QWaitCondition是Qt框架提供的条件变量类用于线程之间的通信和同步在某个条件满足时等待或唤醒线程用于线程的同步和协调
QMutex mutex;
QWaitCondition condition;//等待线程中
mutex.lock();//检查条件是否满足不满足就等待
while (!conditionFullfilled())
{condition.wait(mutex);//条件满足释放锁
}mutex.unlock();//------------------------------------------------------------------------------------//在改变条件的线程中
mutex.lock();
//改变条件
changeCondition();
condition.wakeAll(); //唤醒等待的线程mutex.unlock();3信号量
QSemaphone是Qt框架提供的计数信号类用于控制同时访问共享资源的线程数量用于限制并发线程数量用于解决一些资源有限的问题
QSemaphore semaphore(2); //同时允许两个线程访问共享资源//在需要访问共享资源的线程中
semaphore.acquire(); //尝试获取信号量若已满则阻塞//访问共享资源
//...
semaphore.release(); //释放信号量
//在另⼀个线程中也要进行类似操作今日分享就到这了~