#ifndef WANGCHUAN_H
#define WANGCHUAN_H
#define WC_QT 1 // 如果当前项目是qt则置1,纯c++则置0
#if WC_QT
#include <QGuiApplication>
#include <QPixmap>
#include <QWidget>
#include <QMenu>
#include <QPoint>
#include <QSize>
#include <QMouseEvent>
#include <QPushButton>
#include <QtDebug>
#include <QDesktopWidget>
#include <QMutex>
#include <QApplication>
#include <QPainter>
#include <QFileDialog>
#include <QEvent>
#include <QDateTime>
#include <QStringList>
#include <QScreen>
#include <QLayout>
#include <QStyle>
#include <QMessageBox>
#include <QRegExpValidator>
#include <QStyleOptionViewItem>
#include <QItemDelegate>
#include <QLineEdit>
#include <QStyledItemDelegate>
#include <QJsonParseError>
#include <QTextCodec>
#endif
#include <vector>
#include <fstream>
#include <filesystem>
#include <iostream>
// 6、输出日志信息到屏幕
// [详细显示输出信息的位置,精确到所在文件的行]
// 使用 : wc_LOG(...) //直接调用宏函数
// 使用c的printf格式进行输出。
// eg:
// wc_LOG("%s%d","输出结果:",23);
// wc_LOG("%s","你好世界!");
// wc_LOG("%d",100);
#define wc_LOG(...){\
printf("%s","\n>> >> >>\n");\
printf("%10s","日志:\n");\
printf("%s%s%s","\t在",__FILE__,"文件中,\n");\
printf("%s%d%s","\t第",__LINE__,"行。\n");\
printf("%s","\t");\
printf(__VA_ARGS__);\
printf("%s","\n<< << <<\n");\
}
/*
* 工具:
*
* 1、<截取屏幕工具>
* 位置——>99行
* 详见:Screenshot
*
* 2、<流布局>
* 位置——>425行
* 功能:
* 【如果软件界面窗口大小发生变化,布局里面的控件,进行自动换行】
* 详见:FlowLayout
*
* 3、<基本消息框>
* 位置——>639行
* 功能:
* 【question消息,疑问消息框;information消息框 信息消息框;warning消息框 警告消息框;critical消息框】
* 详见:Message
*
* 4、<正则表达式>
* 位置——>736行
* 功能:
* 包含(用于给表格设置正则表达式,)
* 总结项目中常用表达式格式
* 详见:Messagebox
*
* 5、<操作文件/目录>
* 位置——>783行
* 功能:
* 【Qt:创建新目录、获取程序所在路经、枚举目录下所有文件、枚举目录下所有目录、清空目录】
* 【c++:删除目录、创建目录、初始化目录u、获取程序所在目录、绝对路经、获取目录下的所有文件、一个文件覆盖另一个文件、删除文件、读取文件内容】
* 详见:FileManage
*
* 6、<输出日志信息到屏幕>
* 位置——>39行
* 功能:
* 【详细显示输出内容所在的文件,以及所在的具体行数】
* 详见:wc_LOG()
*
*/
namespace wangchuan{
#if WC_QT
namespace Screenshot
{
// 1、截取屏幕工具
// 使用 : ScreenWidget::Instance()->showFullScreen(); //直接调用实例
// 可以在程序重写一个键盘事件,通过快捷键来调用该实例
// eg:
// virtual void keyPressEvent(QKeyEvent * event) override
// {
// switch (event->key())
// {
// // F1键
// case Qt::Key_F1:
// qDebug() <<"F1";
// wangchuan::Screenshot::ScreenWidget::Instance()->showFullScreen(); //直接调用实例
// break;
// }
// }
#define STRDATETIME qPrintable (QDateTime::currentDateTime().toString("yyyy-MM-dd-HH-mm-ss"))
//截屏对象类
class Screen
{
public:
enum STATUS {SELECT, MOV, SET_W_H};
Screen() {}
Screen(QSize size)
{
maxWidth = size.width();
maxHeight = size.height();
startPos = QPoint(-1, -1);
endPos = startPos;
leftUpPos = startPos;
rightDownPos = startPos;
status = SELECT;
}
void setStart(QPoint pos)
{
startPos = pos;
}
void setEnd(QPoint pos)
{
endPos = pos;
leftUpPos = startPos;
rightDownPos = endPos;
cmpPoint(leftUpPos, rightDownPos);
}
QPoint getStart()
{
return startPos;
}
QPoint getEnd()
{
return endPos;
}
QPoint getLeftUp()
{
return leftUpPos;
}
QPoint getRightDown()
{
return rightDownPos;
}
STATUS getStatus()
{
return status;
}
void setStatus(STATUS status)
{
this->status = status;
}
int width()
{
return maxWidth;
}
int height()
{
return maxHeight;
}
bool isInArea(QPoint pos) // 检测pos是否在截图区域内
{
if (pos.x() > leftUpPos.x() && pos.x() < rightDownPos.x() && pos.y() > leftUpPos.y() && pos.y() < rightDownPos.y()) {
return true;
}
return false;
}
void move(QPoint p) // 按 p 移动截图区域
{
int lx = leftUpPos.x() + p.x();
int ly = leftUpPos.y() + p.y();
int rx = rightDownPos.x() + p.x();
int ry = rightDownPos.y() + p.y();
if (lx < 0) {
lx = 0;
rx -= p.x();
}
if (ly < 0) {
ly = 0;
ry -= p.y();
}
if (rx > maxWidth) {
rx = maxWidth;
lx -= p.x();
}
if (ry > maxHeight) {
ry = maxHeight;
ly -= p.y();
}
leftUpPos = QPoint(lx, ly);
rightDownPos = QPoint(rx, ry);
startPos = leftUpPos;
endPos = rightDownPos;
}
private:
QPoint leftUpPos, rightDownPos; //记录 截图区域 左上角、右下角
QPoint startPos, endPos; //记录 鼠标开始位置、结束位置
int maxWidth, maxHeight; //记录屏幕大小
STATUS status; //三个状态: 选择区域、移动区域、设置width height
void cmpPoint(QPoint &leftTop, QPoint &rightDown)//比较两位置,判断左上角、右下角
{
QPoint l = leftTop;
QPoint r = rightDown;
if (l.x() <= r.x()) {
if (l.y() <= r.y()) {
;
} else {
leftTop.setY(r.y());
rightDown.setY(l.y());
}
} else {
if (l.y() < r.y()) {
leftTop.setX(r.x());
rightDown.setX(l.x());
} else {
QPoint tmp;
tmp = leftTop;
leftTop = rightDown;
rightDown = tmp;
}
}
}
};
//截屏窗口类
class ScreenWidget : public QWidget
{
Q_OBJECT
public:
static ScreenWidget *Instance()
{
// if (self.isNull()) {
// static QMutex mutex;
// QMutexLocker locker(&mutex);
// if (self.isNull()) {
// self.reset(new ScreenWidget);
// }
// }
// return self.data();
static auto screenw = new ScreenWidget;
return screenw;
}
explicit ScreenWidget(QWidget *parent = 0)
{
//this->setWindowFlags(Qt::Tool | Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint | Qt::X11BypassWindowManagerHint);
menu = new QMenu(this);
menu->addAction("保存当前截图", this, SLOT(saveScreen()));
menu->addAction("保存全屏截图", this, SLOT(saveFullScreen()));
menu->addAction("截图另存为", this, SLOT(saveScreenOther()));
menu->addAction("全屏另存为", this, SLOT(saveFullOther()));
menu->addAction("退出截图", this, SLOT(hide()));
//取得屏幕大小
screen = new Screen(QApplication::desktop()->size());
//保存全屏图像
fullScreen = new QPixmap();
}
private:
// static QScopedPointer<ScreenWidget> self;
QMenu *menu; //右键菜单对象
Screen *screen; //截屏对象
QPixmap *fullScreen; //保存全屏图像
QPixmap *bgScreen; //模糊背景图
QPoint movPos; //坐标
protected:
void contextMenuEvent(QContextMenuEvent *e)
{
this->setCursor(Qt::ArrowCursor);
menu->exec(cursor().pos());
}
void mousePressEvent(QMouseEvent *e)
{
int status = screen->getStatus();
if (status == Screen::SELECT) {
screen->setStart(e->pos());
} else if (status == Screen::MOV) {
if (screen->isInArea(e->pos()) == false) {
screen->setStart(e->pos());
screen->setStatus(Screen::SELECT);
} else {
movPos = e->pos();
this->setCursor(Qt::SizeAllCursor);
}
}
this->update();
}
void mouseMoveEvent(QMouseEvent *e)
{
if (screen->getStatus() == Screen::SELECT) {
screen->setEnd(e->pos());
} else if (screen->getStatus() == Screen::MOV) {
QPoint p(e->x() - movPos.x(), e->y() - movPos.y());
screen->move(p);
movPos = e->pos();
}
this->update();
}
void mouseReleaseEvent(QMouseEvent *e)
{
if (screen->getStatus() == Screen::SELECT) {
screen->setStatus(Screen::MOV);
} else if (screen->getStatus() == Screen::MOV) {
this->setCursor(Qt::ArrowCursor);
}
}
void paintEvent(QPaintEvent *)
{
int x = screen->getLeftUp().x();
int y = screen->getLeftUp().y();
int w = screen->getRightDown().x() - x;
int h = screen->getRightDown().y() - y;
QPainter painter(this);
QPen pen;
pen.setColor(Qt::green);
pen.setWidth(2);
pen.setStyle(Qt::DotLine);
painter.setPen(pen);
painter.drawPixmap(0, 0, *bgScreen);
if (w != 0 && h != 0) {
painter.drawPixmap(x, y, fullScreen->copy(x, y, w, h));
}
painter.drawRect(x, y, w, h);
pen.setColor(Qt::yellow);
painter.setPen(pen);
painter.drawText(x + 2, y - 8, tr("截图范围:( %1 x %2 ) - ( %3 x %4 ) 图片大小:( %5 x %6 )")
.arg(x).arg(y).arg(x + w).arg(y + h).arg(w).arg(h));
}
void showEvent(QShowEvent *)
{
QPoint point(-1, -1);
screen->setStart(point);
screen->setEnd(point);
#if (QT_VERSION <= QT_VERSION_CHECK(5,0,0))
*fullScreen = fullScreen->grabWindow(QApplication::desktop()->winId(), 0, 0, screen->width(), screen->height());
#else
QScreen *pscreen = QApplication::primaryScreen();
*fullScreen = pscreen->grabWindow(QApplication::desktop()->winId(), 0, 0, screen->width(), screen->height());
#endif
//设置透明度实现模糊背景
QPixmap pix(screen->width(), screen->height());
pix.fill((QColor(160, 160, 160, 200)));
bgScreen = new QPixmap(*fullScreen);
QPainter p(bgScreen);
p.drawPixmap(0, 0, pix);
}
private slots:
void saveScreen()
{
int x = screen->getLeftUp().x();
int y = screen->getLeftUp().y();
int w = screen->getRightDown().x() - x;
int h = screen->getRightDown().y() - y;
QString fileName = QString("%1/screen_%2.png").arg(qApp->applicationDirPath()).arg(STRDATETIME);
fullScreen->copy(x, y, w, h).save(fileName, "png");
close();
}
void saveFullScreen()
{
QString fileName = QString("%1/full_%2.png").arg(qApp->applicationDirPath()).arg(STRDATETIME);
fullScreen->save(fileName, "png");
close();
}
void saveScreenOther()
{
QString name = QString("%1.png").arg(STRDATETIME);
QString fileName = QFileDialog::getSaveFileName(this, "保存图片", name, "png Files (*.png)");
if (!fileName.endsWith(".png")) {
fileName += ".png";
}
if (fileName.length() > 0) {
int x = screen->getLeftUp().x();
int y = screen->getLeftUp().y();
int w = screen->getRightDown().x() - x;
int h = screen->getRightDown().y() - y;
fullScreen->copy(x, y, w, h).save(fileName, "png");
close();
}
}
void saveFullOther()
{
QString name = QString("%1.png").arg(STRDATETIME);
QString fileName = QFileDialog::getSaveFileName(this, "保存图片", name, "png Files (*.png)");
if (!fileName.endsWith(".png")) {
fileName += ".png";
}
if (fileName.length() > 0) {
fullScreen->save(fileName, "png");
close();
}
}
};
//QScopedPointer<ScreenWidget> ScreenWidget::self;
}
namespace FlowLayout {
// 2、流布局
// 功能 : 如果软件界面窗口大小发生变化,布局里面的控件,进行自动换行
// 使用 : 如下
//auto layout = new wangchuan::FlowLayout::FlowLayout(ui->widget); // ui->widget:任意widget
// layout->addWidget(new QPushButton("1"));
// layout->addWidget(new QPushButton("2"));
// layout->addWidget(new QPushButton("3"));
// layout->addWidget(new QPushButton("5"));
// layout->addWidget(new QPushButton("6"));
// layout->addWidget(new QPushButton("7"));
class FlowLayout : public QLayout
{
public:
/*
* 在构造函数中,我们调用setContentsMargins()来设置
* 左、上、右和下边距。默认情况下,
* QLayout使用当前样式提供的值(请参见QStyle::PixelMetric)。
*/
FlowLayout(QWidget *parent, int margin = -1, int hSpacing = -1, int vSpacing = -1)
: QLayout(parent), m_hSpace(hSpacing), m_vSpace(vSpacing)
{
setContentsMargins(margin, margin, margin, margin);
}
FlowLayout(int margin = -1, int hSpacing = -1, int vSpacing = -1)
: m_hSpace(hSpacing), m_vSpace(vSpacing)
{
setContentsMargins(margin, margin, margin, margin);
}
~FlowLayout()
{
QLayoutItem *item;
while ((item = takeAt(0)))
delete item;
}
/*
* 在本例中,我们重新实现了addItem(),
* 它是一个纯虚拟函数。使用addItem()时,
* 布局项的所有权会转移到布局,因此布局有责任删除它们。
*
* addItem()用于将项添加到布局中。
*/
void addItem(QLayoutItem *item)
{
itemList.append(item);
}
/*
* 我们实现horizontalSpacing()和verticalSpacing。
* 如果该值小于或等于0,则将使用该值。否则,将调用smartSpacing()来计算间距。
*/
int horizontalSpacing() const
{
if (m_hSpace >= 0) {
return m_hSpace;
} else {
return smartSpacing(QStyle::PM_LayoutHorizontalSpacing);
}
}
int verticalSpacing() const
{
if (m_vSpace >= 0) {
return m_vSpace;
} else {
return smartSpacing(QStyle::PM_LayoutVerticalSpacing);
}
}
/*
* expandingDirections()返回Qt::Orientations,其中布局可以使用比其sizeHint()更多的空间。
*/
Qt::Orientations expandingDirections() const
{
return 0;
}
/*
* 为了适应高度取决于宽度的小部件,我们实现了heightForWidth()。
* 函数hasHeightForWidth()用于测试此依赖关系,heightForWidth()将宽度传递给doLayout(),
* doLayout又将宽度用作布局矩形的参数,即项目布局的边界。此矩形不包括布局边距()。
*/
bool hasHeightForWidth() const
{
return true;
}
int heightForWidth(int width) const
{
int height = doLayout(QRect(0, 0, width, 0), true);
return height;
}
/*
* 然后我们实现count()来返回布局中的项数。为了浏览项目列表,
* 我们使用itemAt()和takeAt()从列表中删除并返回项目。
* 如果某个项目被删除,则其余项目将重新编号。这三个函数都是QLayout中的纯虚拟函数。
*/
int count() const
{
return itemList.size();
}
QLayoutItem *itemAt(int index) const
{
return itemList.value(index);
}
QSize minimumSize() const
{
QSize size;
QLayoutItem *item;
foreach (item, itemList)
size = size.expandedTo(item->minimumSize());
size += QSize(2*margin(), 2*margin());
return size;
}
/*
* setGeometry()通常用于进行实际布局,即计算布局项的几何图形。
* 在本例中,它调用doLayout()并传递布局rect。
* sizeHint()返回布局的首选大小,minimumSize()返回版面的最小大小。
*/
void setGeometry(const QRect &rect)
{
QLayout::setGeometry(rect);
doLayout(rect, false);
}
QSize sizeHint() const
{
return minimumSize();
}
QLayoutItem *takeAt(int index)
{
if (index >= 0 && index < itemList.size())
return itemList.takeAt(index);
else
return 0;
}
private:
/*
* 如果horizontalSpacing()或verticalSpacing)未返回默认值,doLayout()将处理布局。
* 它使用getContentsMargins()来计算布局项可用的面积。
*/
int doLayout(const QRect &rect, bool testOnly) const
{
int left, top, right, bottom;
getContentsMargins(&left, &top, &right, &bottom);
QRect effectiveRect = rect.adjusted(+left, +top, -right, -bottom);
int x = effectiveRect.x();
int y = effectiveRect.y();
int lineHeight = 0;
// 然后,它根据当前样式为布局中的每个小部件设置适当的间距。
QLayoutItem *item;
foreach (item, itemList)
{
QWidget *wid = item->widget();
int spaceX = horizontalSpacing();
if (spaceX == -1)
spaceX = wid->style()->layoutSpacing(
QSizePolicy::PushButton, QSizePolicy::PushButton, Qt::Horizontal);
int spaceY = verticalSpacing();
if (spaceY == -1)
spaceY = wid->style()->layoutSpacing(
QSizePolicy::PushButton, QSizePolicy::PushButton, Qt::Vertical);
//然后通过将项目宽度和行高度添加到初始x和y坐标来计算布局中每个项目的位置。
//这反过来又让我们了解下一个项目是否适合当前行,或者是否必须向下移动到下一个。
//我们还根据窗口小部件的高度来查找当前行的高度。
int nextX = x + item->sizeHint().width() + spaceX;
if (nextX - spaceX > effectiveRect.right() && lineHeight > 0) {
x = effectiveRect.x();
y = y + lineHeight + spaceY;
nextX = x + item->sizeHint().width() + spaceX;
lineHeight = 0;
}
if (!testOnly)
item->setGeometry(QRect(QPoint(x, y), item->sizeHint()));
x = nextX;
lineHeight = qMax(lineHeight, item->sizeHint().height());
}
return y + lineHeight - rect.y() + bottom;
}
/*
* smartSpacing()用于获取顶级布局或子布局的默认间距。
* 当父布局是QWidget时,顶级布局的默认间距将通过查询样式来确定。
* 当父布局是QLayout时,子布局的默认间距将通过查询父布局的间距来确定。
*/
int smartSpacing(QStyle::PixelMetric pm) const
{
QObject *parent = this->parent();
if (!parent) {
return -1;
} else if (parent->isWidgetType()) {
QWidget *pw = static_cast<QWidget *>(parent);
return pw->style()->pixelMetric(pm, 0, pw);
} else {
return static_cast<QLayout *>(parent)->spacing();
}
}
QList<QLayoutItem *> itemList;
int m_hSpace;
int m_vSpace;
};
}
namespace Messagebox {
// 3、基本消息框
// 功能:实现常用的消息输出框
// 【0:question消息;1:information消息框 ;2:warning消息框;3:critical消息框;4:普通消息框】
// 使用:在使用消息框的地方,实例化Message对象,在构造函数中:第一个参数是要使用的消息框的索引[0-4],
// 第二个参数:标题,第三个参数内容,第四个参数父指针(默认为空指针)
// 可以根据 execute函数返回的值,执行一些操作『双选:<确认:1,取消:0> ,单选:<0>』
// eg:
// wangchuan::Messagebox::Message messge(0,(char*)"标题",(char*)"内容");
// int num = messge.execute();
class Message{
private:
QWidget* parent{};
int& index;
char* title{nullptr};
char* text{nullptr};
public:
explicit Message(int ind, char* tit, char* tet,QWidget* pt = nullptr)
:
index(ind)
,title(tit)
,text(tet)
,parent(pt)
{
if(!strcmp("",tit)||!strcmp("",tet))
{
title = (char*)"弹窗标题";
text = (char*)"弹窗内容";
}
}
public:
int execute()
{
QMessageBox::ButtonRole result{};
QMessageBox messbo;
messbo.setParent(parent);
messbo.setWindowFlags(Qt::Dialog);
switch (index)
{
case 0:
{
// question 疑问消息框
messbo.setIcon(QMessageBox::Question);
messbo.setWindowTitle(title);
messbo.setText(text);
messbo.addButton("取消", QMessageBox::NoRole);
messbo.addButton("确定",QMessageBox::YesRole);
result = (QMessageBox::ButtonRole)messbo.exec();
}
break;
case 1:
// information 提示消息框
{
messbo.setIcon(QMessageBox::Information);
messbo.setWindowTitle(title);
messbo.setText(text);
messbo.addButton("确定",QMessageBox::YesRole);
result = (QMessageBox::ButtonRole)messbo.exec();
}
break;
case 2:
// warning 警告消息框
{
messbo.setIcon(QMessageBox::Warning);
messbo.setWindowTitle(title);
messbo.setText(text);
messbo.addButton("取消", QMessageBox::NoRole);
result = (QMessageBox::ButtonRole)messbo.exec();
}
break;
case 3:
// critical “操作错误”或“运行失败” 消息框
{
messbo.setIcon(QMessageBox::Critical);
messbo.setWindowTitle(title);
messbo.setText(text);
messbo.addButton("关闭", QMessageBox::NoRole);
result = (QMessageBox::ButtonRole)messbo.exec();
}
break;
case 4:
// NoIcon 普通“没有图标” 消息框
{
messbo.setIcon(QMessageBox::NoIcon);
messbo.setWindowTitle(title);
messbo.setText(text);
messbo.addButton("确认", QMessageBox::NoRole);
result = (QMessageBox::ButtonRole)messbo.exec();
}
break;
}
return (int)result;
}
};
}
namespace RegExp {
// 4、 正则表达式
//
// 功能:实现项目中用到的正则表达式
//
// 【1:限制输入空格、空值,getNullValueRegexp();】
// 使用:在使用正则的地方实例化该对象,通过get方法获取到QRegExpValidator
//
// eg :
// wangchuan::RegExp::Regexp* regexp = new wangchuan::RegExp::Regexp();
// ui->lineedit->setValidator(regexp->getNullValueRegexp());
class Regexp
{
public:
Regexp() = default;
Regexp(Regexp&) = delete;
Regexp(const Regexp&) = delete;
Regexp& operator=(const Regexp&) = delete;
public:
QRegExpValidator* getNullValueRegexp()
{
QRegExp rx("[^\\s]+$");
QRegExpValidator *mNullValue = new QRegExpValidator(rx);
return mNullValue;
}
};
// 用于给表格设置正则表达式,
// table视图 QTableView了
// table模型 QStandardItemModel
// 使用示例:
// wangchuan::RegExp::InputDelegate* inputDelegate = new wangchuan::RegExp::InputDelegate;
// m_tableview->setItemDelegateForColumn(0, inputDelegate); // 设置索引0列的输入正则表达式
class InputDelegate:public QStyledItemDelegate
{
public:
QWidget *createEditor(QWidget*parent,const QStyleOptionViewItem &option,const QModelIndex &index)const override
{
QLineEdit *editor =new QLineEdit(parent);
QRegExp regex("[^\\s]+$"); // 可以替换为你想要的正则表达式
QValidator *validator =new QRegExpValidator(regex,parent);
editor->setValidator(validator);
return editor;
}
};
}
namespace FileManage {
// 5、 对文件操作
//
// 功能:
// 【Qt:创建新目录、获取程序所在路经、枚举目录下所有文件、枚举目录下所有目录、清空目录】
// 【c++:删除目录、创建目录、初始化目录u、获取程序所在目录、绝对路经、获取目录下的所有文件、一个文件覆盖另一个文件、删除文件、读取文件内容】
//
// 说明:纯c++对文件操作有的需要c++17,默认禁用c++17操作,如果开发环境支持c++17,关闭禁用,0——>1;
//
// 使用:
// 引入头文件 通过命名空间进行调用
// eg :
// std::string content = wangchuan::FileManage::StdFile::readFile("filepath");
//
using namespace std;
class StdFile{
public:
StdFile() = delete;
#if 0
// C++ 版本
/** c++17
* @brief 删除目录
* @param path 路经
*/
static void rmDir(const std::string &path)
{
if (filesystem::exists(path)) {
filesystem::remove_all(path);
filesystem::remove(path);
}
}
/** c++17
* @brief 创建目录
* @param path 路经
*/
static void mkDir(const std::string &path)
{
if (!filesystem::exists(path)) {
filesystem::create_directories(path);
}
}
/** c++17
* @brief 初始化目录
* @param path 路经
*/
static void initDir(const std::string &path)
{
if (filesystem::exists(path)) {
filesystem::remove_all(path);
} else {
filesystem::create_directories(path);
}
}
/** c++17
* @brief 获取当前程序所在目录
* @param
* @return std::string 返回程序所在路经
*/
static std::string curPath()
{
#if defined(_MSC_VER)
return filesystem::current_path().string();
#else
return filesystem::current_path();
#endif
}
/** c++17
* @brief 绝对路经
* @param path 路经
* @return std::string
*/
static std::string absolutePath(const std::string &path)
{
#if defined(_MSC_VER)
return filesystem::canonical(path).string();
#else
return filesystem::canonical(path);
#endif
}
/** c++17
* @brief 获取目录下的所有文件
* @param path 路经
* @return std::vector<std::string> 返回所欧文件的vector
*/
static std::vector<std::string> listFiles(const std::string &path)
{
vector<string> res;
if (!filesystem::exists(path)) {
return res;
}
for (const auto &entry : filesystem::directory_iterator(path)) {
if (filesystem::is_regular_file(entry)) {
#if defined(_MSC_VER)
string fileName = entry.path().stem().string();
string ext = entry.path().extension().string();
#else
string fileName = entry.path().stem();
string ext = entry.path().extension();
#endif
auto file = fileName + ext;
res.push_back(file);
}
}
return res;
}
/** c++17
* @brief 拷贝文件(覆盖),覆盖后还使用旧文件名。
* @param 要拷贝的文件, 被覆盖的文件
* @return
*/
static void copyFile(const std::string &from, const std::string &to)
{
filesystem::copy_file(from, to, filesystem::copy_options::overwrite_existing);
}
/** c++17
* @brief 删除文件
* @param path 文件路经
* @return
*/
static void rmFile(const std::string &file)
{
if (filesystem::exists(file)) {
filesystem::remove(file);
}
}
#endif
/**
* @brief 读取文件内容
* @param path 文件路经
* @return std::string 读取到的内容
*/
static std::string readFile(const std::string &filePath)
{
string res{""};
ifstream f;
f.open(filePath, ios::in);
if (f.is_open()) {
f.seekg(0, ios::end);
int len = f.tellg();
if (len > 0) {
f.seekg(0, ios::beg);
res.resize(len);
f.read((char *)res.data(), len);
}
f.close();
}
return res;
}
// Qt版
/**
* @brief 创建新目录
* @param path 目录路经
* @return
*/
static void mkDir(const QString &path)
{
QDir dir{path};
if (!dir.exists()) {
dir.mkpath(path);
}
}
/**
* @brief 获取程序工作目录
* @param path 目录路径
* @return
*/
static QString workDir()
{
static QString path = "";
if (path.length() <= 0) {
path = QApplication::applicationDirPath() + "/../data";
QDir dir{path};
path = dir.absolutePath();
mkDir(path);
}
return path;
}
/**
* @brief 枚举目录下所有文件
* @param dir 要枚举的目录
* @return 符合条件的所有文件列表
*/
static std::vector<QString> listFiles(const QString &dir)
{
vector<QString> res;
QDir dd{dir};
auto fl = dd.entryInfoList(QDir::Files);
for (const auto &file : fl) {
if (file.isFile()) {
//res.push_back(file.absoluteFilePath());
res.push_back(file.fileName());
}
}
return res;
}
/**
* @brief 枚举目录下所有目录
* @param dir 要枚举的目录
* @return 符合条件的所有目录列表
*/
static std::vector<QString> listDirs(const QString &dir)
{
vector<QString> res;
QDir dd{dir};
auto fl = dd.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot);
for (const auto &file : fl) {
if (file.isDir()) {
res.push_back(file.fileName());
}
}
return res;
}
/**
* @brief 清空目录
* @param path 要清空的目录
* @return
*/
static void clearDir(const QString &dir)
{
QDir dd{dir};
auto fl = dd.entryInfoList(QDir::AllEntries | QDir::NoDotAndDotDot);
for (const auto &file : fl) {
auto path = file.absoluteFilePath();
if (file.isFile()) {
dd.remove(path);
} else {
clearDir(path);
dd.rmpath(path);
}
}
}
/**
* @brief 读取文件内容
* @param path 文件路径
* @return
*/
static QString gReadFileAll(const QString& path, const QString& _type = "utf-8")
{
QString _allContent;
QFile _file(path);
if (!_file.open(QIODevice::ReadOnly | QIODevice::Text))
return _allContent;
QTextStream _stream(&_file);
_stream.setCodec(QTextCodec::codecForName(_type.toStdString().c_str()));
_allContent = _stream.readAll();
_file.close();
return _allContent;
}
/**
* @brief 往文件里写内容
* @param path 文件路径, content 要写入的内容, _type编码格式
* @return
*/
static void gWriteFile(const QString& path, const QString& content, const QString& _type = "utf-8")
{
QFile _file(path);
if (!_file.open(QIODevice::Truncate | QIODevice::ReadWrite| QIODevice::Text))
return;
QTextStream _stream(&_file);
_stream.setCodec(QTextCodec::codecForName(_type.toStdString().c_str()));
_stream << content;
_file.close();
}
/**
* @brief 拷贝目录到另一个目录中
* @param _source 要拷贝的文件路径,_target拷贝到哪,couver bool是否覆盖,suffix 过滤指定格式的文件
* @return
*/
static void gCopyDirToDir(const QString& _source, const QString& _target, bool cover, const QString& suffix)
{
QDir dir(_source);
//获取文件列表
QFileInfoList list = dir.entryInfoList(QDir::Files | QDir::NoSymLinks);
for (auto _info : list)
{
if (!suffix.isEmpty() && suffix!= _info.suffix())
{
continue;
}
QString path = _info.absoluteFilePath();
//目标路径
QString toFile = _target;
toFile += "/";
toFile += _info.fileName();
if (cover)
{
gDeleteFile(toFile);
}
QFile tempFile(path);
tempFile.copy(toFile);
tempFile.close();
}
}
/**
* @brief 拷贝文件到目录
* @param source 文件绝对路径,target 目录路径, cover bool是否进行覆盖
* @return
*/
static bool gCopyFileToDir(const QString& source, const QString& target, bool cover)
{
QFileInfo sourceInfo(source);
if (!sourceInfo.exists())
return false;
QString toFile = target;
toFile += "/";
toFile += sourceInfo.fileName();
if (cover)
{
gDeleteFile(toFile);
}
QFile tempFile(source);
tempFile.copy(toFile);
tempFile.close();
return true;
}
/**
* @brief 删除文件
* @param path 文件绝对路径
* @return
*/
static void gDeleteFile(const QString& path)
{
QFileInfo toFileInfo(path);
if (toFileInfo.exists())
{
toFileInfo.dir().remove(toFileInfo.fileName());
}
}
/**
* @brief 删除目录
* @param path 目录路径
* @return
*/
static void gDeleteDir(const QString& _path)
{
QDir _dir(_path);
if (!_dir.exists())
{
return;
}
_dir.setFilter(QDir::AllEntries | QDir::NoDotAndDotDot);
QFileInfoList _fileList = _dir.entryInfoList();
foreach(QFileInfo _file, _fileList)
{
if (_file.isFile())
{
_file.dir().remove(_file.fileName());
}
else
{
gDeleteDir(_file.absoluteFilePath());
}
}
_dir.rmdir(_dir.absolutePath());
}
/**
* @brief 删除目录
* @param path 目录路径
* @return
*/
static QString gToJsonOfObject(const QJsonObject& object)
{
QJsonDocument jsonDocument;
jsonDocument.setObject(object);
return jsonDocument.toJson(QJsonDocument::Indented);
}
static void gDeleteSubString(QString& content, const QString& start, const QString& end)
{
int startIndex = content.indexOf(start);
int endIndex = content.indexOf(end, startIndex);
while (startIndex != -1 && endIndex != -1)
{
content.remove(startIndex, endIndex - startIndex + end.length() + 1);
startIndex = content.indexOf(start);
endIndex = content.indexOf(end, startIndex);
}
}
static void gDeleteSubString(QString& content, const QString& startFlag, const QString& ifFlag, const QString& endFlag)
{
int startIndex = content.indexOf(startFlag);
int endIndex = content.indexOf(endFlag, startIndex);
while (startIndex != -1 && endIndex != -1)
{
int index = content.indexOf(ifFlag, startIndex);
if (index != -1 && endIndex > index)
{
index = content.indexOf(endFlag, index);
if (index != -1)
{
content.remove(startIndex, index - startIndex + endFlag.length() + 1);
}
}
startIndex = content.indexOf(startFlag, endIndex);
endIndex = content.indexOf(endFlag, startIndex);
}
}
};
}
#endif
}
#endif // WANGCHUAN_H