(一)目录和定时器
-
目录操作QDir
1)创建目录对象
QDir dir("./photos");
2)遍历目录下的内容
QStringList list = dir.entryList(Filters filters);
filters:
–>QDir::Dirs 只访问目录文件
–>QDir::Files 只访问普通文件
–>QDir::NoDotAndDotDot 不包括".“和”…" -
定时器
1)方法一:定时器事件 timerEvent
//定时器事件处理函数
virtual void timerEvent(QTimerEvent*);
//开启定时器,参数是间隔时间(毫秒),返回定时器ID
int startTimer(int interval);
//关闭定时器
void killTimer(int id);2)方法二:定时器类 QTimer
//创建定时器对象
QTimer timer;
//连接定时器处理的槽函数
connect(&timer,SIGNAL(timeout(void)),
this,SLOT(mySlot(void)));
//开启定时器
timer.start(int msec);
//关闭定时器
timer.stop();案例:摇奖机
1)创建工程
工程名:Lottery
类名:LotteryDialog
2)将"photos"拷贝到工程目录下
3)到项目模式,去掉“shadow build”勾选
4)界面设计
–>父窗口
font:点大小(20)
windowTitle:摇摇乐
–>Frame
sizePolicy:垂直策略(expanding)
frameShape:box
–>PushButton
text:开始
(二)鼠标和键盘
-
鼠标事件
#include
//鼠标按下时执行的事件处理函数
virtual void mousePressEvent(QMouseEvent*);
//鼠标抬起时执行的事件处理函数
virtual void mouseReleaseEvent(QMouseEvent*);
//鼠标移动时执行的事件处理函数
virtual void mouseMoveEvent(QMouseEvent*);
//鼠标双击时执行的时间处理函数
virtual void mouseDoubleClickEvent(QMouseEvent*);
QRect(x,y,w,h)//矩形区域
QPoint(x,y)//位置
QSize(w,h)//大小
案例:通过鼠标左键拖拽label移动
1)工程名:Mouse
2)类名:MouseDialog
3)界面设计(label)
–>frameShape:Box
–>frameShadow:Raised
–>设置背景颜色
方法1:调色板
–>autoFillBackground:勾选
–>palette:点击“继承”->改变调色板->选择颜色
方法2:样式表
–>styleSheet:
编辑样式表->添加颜色->background-color->选择颜色 -
键盘事件
#include <QKeyEvent>
//键盘按键按下时执行的事件处理函数
virtual void keyPressEvent(QKeyEvent*);
//键盘按键抬起时执行的事件处理函数
virtual void keyRelaseEvent(QKeyEvent*);案例:通过键盘方向键,控制label移动
1)工程名:Keyboard
2)类名:KeyboardDialog
(三)Qt多线程(QThread)
-
创建线程
1)方法1:moveToThread//Worker自定义,需要放入子线程中工作类 class Worker:public QObject{ Q_OBJECT public slots: //需要放入子线程中执行的具体代码(槽函数) void doWork(...) { /*耗时或阻塞操作*/ } };
//创建子线程对象 QThread workerThread; //创建需要在子线程工作的worker对象 Worker *worker = new Worker; //将worker对象移动到子线程中 worker->moveToThread(&workerThread); //连接信号和槽 connect(xx,SIGNAL(xx),worker,SLOT(doWork(..))); //开启子线程,当信号发射时,dowork槽函数将在子线程执行 workerThread.start();
2)方法2:继承QThread,重写run函数
class WorkerThread : public QThread{ protected: //重写线程入口函数 virtual void run(void){ //耗时或阻塞任务 } }; WorkerThread thread; thread.start();//实际被执行的将是子类中重写版本
-
主要的成员函数
1)开启线程//类似pthread_create()
void start()
2)获取线程句柄(ID)//类似pthread_self
Qt::HANDLE currentThreadId()
3)线程退出//类似pthread_exit
void exit();
void quit()[slot];
4)线程等待//类似pthread_join
void wait();
5)线程终止//类似pthread_cancel
void terminate()//线程意外终止风险:
void run(void){ new内存; //被终止,delete语句执行不到,内存泄漏 delete内存; } void run(void){ 加锁:mutex.lock() //访问临界资源 //被终止,死锁! 解锁:mutex.unlock() } //解决:setTerminationEnabled() void run(void){ setTerminationEnabled(false);//不允许被终止 //关键代码:动态资源管理,临界资源访问,数据库访问.. setTerminationEnabled(true);//恢复可以被终止 }
案例:
多线程打印消息:Thread1 //方法一
多线程打印消息:Thread2 //方法二 -
线程同步
1)互斥锁/互斥量:QMutexQMutex mutex; void run(void){ mutex.lock(); //访问临界资源ing if("error1"){ mutex.unlock(); return; } if("error2"){ mutex.unlock(); return; } //访问临界资源end mutex.unlock(); } QMutex mutex; void run(void){ //mutex.lock(); QMutexLocker locker(&mutex); //访问临界资源ing if("error1"){ return; } if("error2"){ return; } //访问临界资源end }//locker析构函数负责解锁
2)读写锁:QReadWriteLock
QReadWriteLock lock; void ReaderThread::run(){//读操作线程 ... lock.lockForRead(); read_file(); lock.unlock(); ... } void WriterThread::run(){//写操作线程 ... lock.lockForWrite(); write_file(); lock.unlock(); ... }
3)信号量:QSemaphore
//初始化信号计数值为5,表示有5个可用的共享资源
QSemaphore sem(5); //sem.available()==5
//获取3个资源,剩余2个可用资源
sem.acquire(3);// sem.available() == 2
//获取2个资源,剩余0个可用资源
sem.acquire(2);// sem.available() == 0
//释放5个资源,剩余5个可用资源
sem.release(5);// sem.available() == 5
//又分配5个资源,剩余10个可用资源
sem.release(5);// sem.available() == 10
//尝试获取1个资源,剩余9个,返回true
sem.tryAcquire(1);//sem.available() == 9,returns true
//尝试获取250个资源,剩余9个,返回false
sem.tryAcquire(250);//sem.available()==9,returns false