我的工具 Qt( 1.< 截图工具> 、2. <流布局,自动换行>、3. <基本消息框>、4.<正则表达式,包含给表格设置>、5.<文件目录操作、读写,拷贝,删除,清空等>、6.<输出信息到屏幕,精确显示信息所在的文件的行>)
#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
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性