如何仿制wordpress网站,网站首页结构怎么写,如何设置网站服务器,平面设计教程自学#x1f4a1; 进度条显示拷贝进度#xff08;verson 1#xff09;
窗口上放置一个按钮和一个进度条部件#xff0c;点击按钮#xff0c;进行拷贝操作 —— 打开对话框选择源文件#xff0c;然后再打开一个对话框 选择 目标文件存放位置和名称。拷贝过程中进度条显示当前… 进度条显示拷贝进度verson 1
窗口上放置一个按钮和一个进度条部件点击按钮进行拷贝操作 —— 打开对话框选择源文件然后再打开一个对话框 选择 目标文件存放位置和名称。拷贝过程中进度条显示当前进度大文件。不允许用QFile 的 copy 方法 —— 把源文件分解开然后一帧一帧写入目标文件。
widget.h
#ifndef WIDGET_H
#define WIDGET_H#include QtWidgetsnamespace Ui {
class Widget;
}class Widget : public QWidget
{Q_OBJECTpublic:explicit Widget(QWidget *parent 0);~Widget();private slots:void on_pushButton_released();private:Ui::Widget *ui;
};#endif // WIDGET_Hwidget.cpp
#include widget.h
#include ui_widget.h#define KB 1024Widget::Widget(QWidget *parent) :QWidget(parent),ui(new Ui::Widget)
{ui-setupUi(this);ui-progressBar-setValue(0);
}Widget::~Widget()
{delete ui;
}void Widget::on_pushButton_released()
{// 1.选定源文件QString srcName QFileDialog::getOpenFileName(this, tr(选择文件), \D:/Packages_, tr(all (*.*)));if (srcName.isEmpty())return ;qDebug() src: srcName;// 2.选定目标文件QString destName QFileDialog::getSaveFileName(this, tr(保存文件), \e:, tr(all (*.*)));if (destName.isEmpty())return ;qDebug() dest: destName;QFile srcFile(srcName);if (!srcFile.open(QIODevice::ReadOnly)){qDebug() 打开文件失败;return ;}QFile destFile(destName);if (!destFile.open(QIODevice::ReadWrite | QIODevice::Truncate)){qDebug() 复制文件失败;return ;}ui-progressBar-setValue(0); // 确保每次点击按钮时进度条都是从 0 开始qint64 totalSize srcFile.size();qint64 currentSize 0;QByteArray buffer;// 3.开始拷贝--不断读取然后写入while (!srcFile.atEnd()){buffer.clear();buffer srcFile.read(KB);destFile.write(buffer);// 4.更新进度值currentSize buffer.size();ui-progressBar-setValue(100 * currentSize / totalSize);}
}运行结果如下复制文件时拖动窗口会产生卡顿
QT 线程
GUI 线程QT 的主线程
QT 的主线程称为 GUI 线程负责初始化界面并监听事件循环并根据事件处理做出界面上的反馈。
使用多线程的好处
1、提高应用界面的响应速度
这对于开发图形界面程序尤其重要当一个操作耗时很长时比如大批量 I/O 或大量矩阵变换等CPU密集操作整个系统都会等待这个操作程序就不能响应键盘、鼠标、菜单等操作而使用多线程技术可将耗时长的操作置于一个新的线程从而不会影响到 主 GUI 线程从而避免上述问题。
2、使多核心 CPU 系统更加有效
当线程数不大于CPU核数时操作系统可以调度不同的线程运行于不同的CPU核上。
3、改善程序结构
一个既长又复杂的进程可以考虑分为多个线程成为独立或半独立的运行部分这样有利于程序的理解和维护。 创建一个界面界面 show 以后调用睡眠函数观察效果。 QThread 类
相关接口
Public Functions:QThread(QObject *parent 0); // 构造函数 // pthread_createbool isFinished() const; // 判断线程是否退出bool wait(unsigned long time ULONG_MAX); // pthread_join(id)// 等待某个线程结束最多等待time ms如果时间没有设置那么永远等待。Public Slots:void start(Priority priority InheritPriority) // 启动线程必须使用startvoid terminate(); // 杀死线程 // pthread_cancelStatic Public Members:Qt::HANDLE currentThreadId() [static] // 得到当前执行者线程ID可以直接qDebugvoid sleep(unsigned long secs) [static]void msleep(unsigned long msecs) [static]void usleep(unsigned long usecs) [static]睡眠函数不能在主线程调用会造成界面卡死。Protected Functions: virtual void run(); // 启动新线程不能直接调用run需要调用 start 接口// start 会启动新线程然后执行run里的代码块。编程流程
1子类化 QThread重写一个类继承自 QThread 2重写 run 函数执行耗时操作run 函数内有一个 while / for 循环 或 sleep 3子线程类实现 公共方法供主线程传参主线程给子线程传参 4主线程内 定义并实例化子线程的类对象 5主线程调用 start 方法 启动子线程 6设置必要的 信号和槽 做连接 —— 子线程给主线程传参 7设置一个标记 来控制循环的退出或者父线程调用 terminate 停止子线程。 注意子线程内不允许操作界面上的任何部件所有界面操作都应该由 GUI 主线程来进行。 练习
重写一个线程子类GUI 线程传递一个值给子线程。界面放置一个按钮点击按钮后线程开始运行。子线程打印主线程传递的值以后睡眠任意时间线程运行结束后通知主线程自己运行的时间主线程把子线程睡眠的总时间显示到界面上。
mythread.h
#ifndef MYTHREAD_H
#define MYTHREAD_H#include QThread
#include qdebug.hclass MyThread : public QThread // 1重写一个类继承自 QThread
{Q_OBJECT
public:explicit MyThread(QObject *parent 0);void setValue(int num) {this-val num;} // 3子线程类实现 公共方法供主线程传参signals:void valueSignal(int); // 6子线程发信号给主线程public slots:private:void run(); // 2重写 run 函数int val;
};#endif // MYTHREAD_Hmythread.cpp
#include mythread.hMyThread::MyThread(QObject *parent) :QThread(parent)
{
}void MyThread::run() // 2重写 run 函数
{qDebug() From parent thread: val val;QThread::sleep(16); // 2run 函数内有一个 while/for 循环 或 sleepemit valueSignal(16);
}widget.h
#define WIDGET_H#include QtWidgets
#include mythread.hnamespace Ui {
class Widget;
}class Widget : public QWidget
{Q_OBJECTpublic:explicit Widget(QWidget *parent 0);~Widget();private:Ui::Widget *ui;MyThread *myth; // 4主线程内 定义子线程的类对象public slots:void valueSlot(int); // 6主线程的槽接收来自子线程的信号private slots:void on_pushButton_clicked();
};#endif // WIDGET_Hwidget.cpp
#include widget.h
#include ui_widget.hWidget::Widget(QWidget *parent) :QWidget(parent),ui(new Ui::Widget)
{ui-setupUi(this);// 4主线程内 实例化子线程的类对象myth new MyThread(this); // 使用 this 的目的仅是方便回收myth-setValue(98); // 4.5主线程传参给子线程// 6设置必要的 信号和槽 做连接QObject::connect(myth, SIGNAL(valueSignal(int)), this, SLOT(valueSlot(int)));
}Widget::~Widget()
{delete ui;
}void Widget::valueSlot(int num) // 6子线程给主线程传参的方式信号与槽
{ui-label-setText(From child thread: val QString::number(num));
}void Widget::on_pushButton_clicked()
{myth-start(); // 5主线程调用 start 方法 启动子线程
}实现效果如下 进度条显示拷贝进度verson 2
newthread.h
#ifndef NEWTHREAD_H
#define NEWTHREAD_H#include QThread
#include QtWidgetsclass NewThread : public QThread
{Q_OBJECT
public:explicit NewThread(QObject *parent 0);void setFileNames(QString src, QString dest){srcName src;destName dest;}signals:void valueSignal(int);public slots:protected:void run();QString srcName;QString destName;int percentage;
};#endif // NEWTHREAD_Hnewthread.cpp
#include newthread.h#define KB 1024NewThread::NewThread(QObject *parent) :QThread(parent)
{
}void NewThread::run()
{QFile srcFile(srcName);if (!srcFile.open(QIODevice::ReadOnly)){qDebug() 打开文件失败;return ;}QFile destFile(destName);if (!destFile.open(QIODevice::ReadWrite | QIODevice::Truncate)){qDebug() 复制文件失败;return ;}qint64 totalSize srcFile.size();qint64 currentSize 0;QByteArray buffer;while (!srcFile.atEnd()){buffer.clear();buffer srcFile.read(KB);destFile.write(buffer);currentSize buffer.size();percentage 100 * currentSize / totalSize;emit valueSignal(percentage);}
}widget.h
#ifndef WIDGET_H
#define WIDGET_H#include QtWidgets
#include newthread.hnamespace Ui {
class Widget;
}class Widget : public QWidget
{Q_OBJECTpublic:explicit Widget(QWidget *parent 0);~Widget();private slots:void on_pushButton_released();private:Ui::Widget *ui;NewThread *thr;public slots:void valueSlot(int);
};#endif // WIDGET_Hwidget.cpp
#include widget.h
#include ui_widget.hWidget::Widget(QWidget *parent) :QWidget(parent),ui(new Ui::Widget)
{ui-setupUi(this);ui-progressBar-setValue(0);thr new NewThread(this);QObject::connect(thr, SIGNAL(valueSignal(int)), this, SLOT(valueSlot(int)));
}Widget::~Widget()
{delete ui;
}void Widget::on_pushButton_released()
{QString srcName QFileDialog::getOpenFileName(this, tr(选择文件), \D:/Packages_, tr(all (*.*)));if (srcName.isEmpty())return ;qDebug() src: srcName;QString destName QFileDialog::getSaveFileName(this, tr(保存文件), \e:, tr(all (*.*)));if (destName.isEmpty())return ;qDebug() dest: destName;ui-progressBar-setValue(0); // 每次启动线程前将进度条的进度 置0thr-setFileNames(srcName, destName);thr-start(); // 不要忘记启动线程
}void Widget::valueSlot(int value)
{ui-progressBar-setValue(value);
}运行结果如下复制文件时拖动窗口不会产生卡顿