510 lines
16 KiB
C++
510 lines
16 KiB
C++
#include <QApplication>
|
||
#include <QLabel>
|
||
#include <QWidget>
|
||
#include <QObject>
|
||
#include <QPushButton>
|
||
#include <QMessageBox>
|
||
#include <QHBoxLayout>
|
||
#include <QDesktopServices>
|
||
#include <QSplitter>
|
||
#include <QTreeView>
|
||
#include <QFileSystemModel>
|
||
#include <QFileDialog>
|
||
#include <QUrl>
|
||
#include <QLineEdit>
|
||
#include <QFontComboBox>
|
||
#include <QSpinBox>
|
||
#include <QCheckBox>
|
||
#include <QColor>
|
||
#include <QColorDialog>
|
||
#include <QDialogButtonBox>
|
||
|
||
#include "ui_mainwindow.h"
|
||
#include "ui_about.h"
|
||
#include "ui_information.h"
|
||
//#include "ui_fontch.h"
|
||
|
||
int main(int argc, char* argv[]){
|
||
QApplication app(argc, argv);
|
||
QIcon icon(":/favicon.ico");
|
||
QMainWindow* M;
|
||
M = new QMainWindow();
|
||
M->setWindowIcon(icon);
|
||
Ui::MainWindow* uu;
|
||
uu = new Ui::MainWindow();
|
||
uu->setupUi(M);
|
||
uu->actionSave->setShortcut(QKeySequence::Save);
|
||
uu->actionOpen->setShortcut(QKeySequence::Open);
|
||
uu->actionNewFile->setShortcut(QKeySequence::New);
|
||
uu->actionDelete->setShortcut(QKeySequence::Delete);
|
||
QString dir;
|
||
|
||
//左侧树状图
|
||
QTreeView* tree = new QTreeView(M);
|
||
tree->resize(50,M->height());
|
||
|
||
//设置文件路径
|
||
QFileSystemModel* model = new QFileSystemModel(M);
|
||
model->setRootPath(QDir::homePath());
|
||
tree->setModel(model);
|
||
QString path = QDir::homePath();
|
||
|
||
//右侧的代码区
|
||
QTextEdit* editor = new QTextEdit;
|
||
QFont codeFont("JetBrains Mono");
|
||
codeFont.setPointSize(11);
|
||
editor->setFont(codeFont);
|
||
//editor->setText("<h3>这里是右侧编辑器区域</h3>");
|
||
|
||
// 在构造函数中添加
|
||
QString placeholder = "这里是右侧编辑器区域";
|
||
|
||
editor->setTextColor(Qt::gray);
|
||
editor->setPlainText(placeholder);
|
||
|
||
// 是否在显示提示文本
|
||
bool showingPlaceholder = true;
|
||
|
||
// 当文本编辑框获得焦点
|
||
QObject::connect(editor, &QTextEdit::textChanged, M, [=]() mutable {
|
||
if (showingPlaceholder && editor->toPlainText() != placeholder && showingPlaceholder == true) {
|
||
showingPlaceholder = false;
|
||
editor->setTextColor(Qt::black);
|
||
editor->clear();
|
||
|
||
}
|
||
});
|
||
|
||
// 如果不想在 textChanged 中重复 setPlainText,可在 focusInEvent/focusOutEvent 中更优雅地控制(进阶可加)
|
||
|
||
//NewFile的时候
|
||
QObject::connect(
|
||
uu->actionNewFile,
|
||
&QAction::triggered,
|
||
M,
|
||
[&](){
|
||
QString fileName = QFileDialog::getSaveFileName(M, "新建文件", QDir::homePath(), "所有文件 (*.*)");
|
||
|
||
if (!fileName.isEmpty()) {
|
||
QFile file(fileName);
|
||
QFileInfo fileinfo(fileName);
|
||
if (file.open(QIODevice::WriteOnly | QIODevice::Text)) {
|
||
file.close(); // 创建空文件(也可以先写入一些内容)
|
||
editor->clear();
|
||
editor->setReadOnly(false);
|
||
path = fileinfo.absolutePath();
|
||
//qDebug() << path << Qt::endl;
|
||
QMessageBox::information(M, "成功", "文件已创建: " + fileName);
|
||
model->setRootPath(path);
|
||
tree->setRootIndex(model->index(path));
|
||
} else {
|
||
QMessageBox::warning(M, "失败", "无法创建文件: " + fileName);
|
||
}
|
||
|
||
}
|
||
}
|
||
);
|
||
|
||
//Open的时候
|
||
QObject::connect(
|
||
uu->actionOpen,
|
||
&QAction::triggered,
|
||
M,
|
||
[&](){
|
||
dir = QFileDialog::getExistingDirectory(M, "选择一个目录", QDir::homePath());
|
||
model->setRootPath(dir);
|
||
tree->setRootIndex(model->index(dir));
|
||
}
|
||
);
|
||
|
||
//Delete的时候
|
||
QObject::connect(
|
||
uu->actionDelete,
|
||
&QAction::triggered,
|
||
M,
|
||
[&]()
|
||
{
|
||
QModelIndex index = tree->currentIndex(); // 获取当前选中的项
|
||
if (!index.isValid()) {
|
||
QMessageBox::warning(M, "未选择", "请先选中要删除的文件或目录。");
|
||
return;
|
||
}
|
||
|
||
QString paths = model->filePath(index);
|
||
QFileInfo info(paths);
|
||
|
||
// 弹出确认对话框
|
||
if (QMessageBox::question(M, "确认删除", "确定要删除吗?\n" + paths)
|
||
!= QMessageBox::Yes) {
|
||
return;
|
||
}
|
||
|
||
bool success = false;
|
||
if (info.isDir()) {
|
||
QDir dir(paths);
|
||
success = dir.removeRecursively(); // 删除整个目录
|
||
} else {
|
||
QFile file(paths);
|
||
success = file.remove(); // 删除单个文件
|
||
}
|
||
|
||
if (success) {
|
||
QMessageBox::information(M, "删除成功", "已删除: " + paths);
|
||
// 刷新当前目录
|
||
QString parentPath = info.absolutePath();
|
||
model->setRootPath("");
|
||
model->setRootPath(parentPath);
|
||
tree->setRootIndex(model->index(parentPath));
|
||
editor->clear();
|
||
} else {
|
||
QMessageBox::warning(M, "删除失败", "无法删除文件或目录。");
|
||
}
|
||
}
|
||
);
|
||
|
||
//Save的时候
|
||
QObject::connect(
|
||
uu->actionSave,
|
||
&QAction::triggered,
|
||
M,
|
||
[&](){
|
||
//save
|
||
if (path.isEmpty()) {
|
||
QMessageBox::warning(M, "错误", "没有打开任何文件!");
|
||
return;
|
||
}
|
||
|
||
QFile file(path);
|
||
QFileInfo fileinfo(path);
|
||
if (file.open(QIODevice::WriteOnly | QIODevice::Text)) {
|
||
QString content = editor->toPlainText();
|
||
file.write(content.toUtf8());
|
||
file.close();
|
||
QMessageBox::information(M, "保存成功", "文件已保存到:" + path);
|
||
QString w = fileinfo.absolutePath();
|
||
model->setRootPath("");
|
||
model->setRootPath(w);
|
||
tree->setRootIndex(model->index(w));
|
||
} else {
|
||
QMessageBox::warning(M, "保存失败", "无法写入文件:" + path);
|
||
}
|
||
}
|
||
);
|
||
|
||
//SaveAs的时候
|
||
QObject::connect(
|
||
uu->actionSaveas,
|
||
&QAction::triggered,
|
||
M,
|
||
[&](){
|
||
QString saveas = QFileDialog::getSaveFileName(M, "另存为", path);
|
||
if (!saveas.isEmpty()) {
|
||
QFile file(saveas);
|
||
if (file.open(QIODevice::WriteOnly | QIODevice::Text)) {
|
||
QString content = editor->toPlainText();
|
||
file.write(content.toUtf8());
|
||
file.close();
|
||
QMessageBox::information(M, "另存为成功", "文件已保存到:" + saveas);
|
||
} else {
|
||
QMessageBox::warning(M, "另存为失败", "无法写入文件:" + saveas);
|
||
}
|
||
}
|
||
else{
|
||
QMessageBox::warning(M, "错误", "文件名称路径设置有误!");
|
||
return;
|
||
}
|
||
}
|
||
);
|
||
|
||
//tree视图中打开代码
|
||
QObject::connect(
|
||
tree,
|
||
&QTreeView::clicked,
|
||
M,
|
||
[&](const QModelIndex& index){
|
||
path = model->filePath(index);
|
||
|
||
QFileInfo info(path);
|
||
if (info.isFile()) {
|
||
QFile file(path);
|
||
if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||
QString content = file.readAll();
|
||
editor->setPlainText(content); // 显示到右侧编辑器
|
||
editor->setReadOnly(false); // 可编辑
|
||
file.close();
|
||
} else {
|
||
editor->setPlainText("无法打开文件:" + dir);
|
||
}
|
||
} else {
|
||
// 如果是目录可以忽略或清空右侧
|
||
editor->clear();
|
||
}
|
||
}
|
||
);
|
||
|
||
//把字体做了----------------------------------------------------------------------------
|
||
//字体大小
|
||
QObject::connect(
|
||
uu->actionSize,
|
||
&QAction::triggered,
|
||
M,
|
||
[&](){
|
||
QDialog* dFont = new QDialog(M);
|
||
dFont->setWindowTitle("设置字体大小");
|
||
dFont->resize(200,100);
|
||
|
||
QLabel *label = new QLabel("请输入字体大小(px):", dFont);
|
||
QLineEdit* input = new QLineEdit(M);
|
||
input->setPlaceholderText("例如:16");
|
||
|
||
QPushButton *okButton = new QPushButton("确定", dFont);
|
||
QPushButton *cancelButton = new QPushButton("取消", dFont);
|
||
|
||
QHBoxLayout *btnLayout = new QHBoxLayout();
|
||
btnLayout->addWidget(okButton);
|
||
btnLayout->addWidget(cancelButton);
|
||
|
||
QVBoxLayout *mainLayout = new QVBoxLayout(dFont);
|
||
mainLayout->addWidget(label);
|
||
mainLayout->addWidget(input);
|
||
mainLayout->addLayout(btnLayout);
|
||
|
||
QObject::connect(okButton, &QPushButton::clicked, dFont, [&](){
|
||
bool ok;
|
||
int fontSize = input->text().toInt(&ok);
|
||
if (ok && fontSize > 0) {
|
||
// 在这里添加设置字体大小的逻辑
|
||
codeFont.setPointSize(fontSize);
|
||
editor->setFont(codeFont);
|
||
dFont->close();
|
||
} else {
|
||
QMessageBox::warning(dFont, "错误", "请输入有效的字体大小");
|
||
}
|
||
});
|
||
QObject::connect(cancelButton, &QPushButton::clicked, dFont, [=](){
|
||
dFont->close();
|
||
});
|
||
|
||
dFont->exec();
|
||
//exec是动态模,比较好,close可以关闭
|
||
|
||
}
|
||
);
|
||
|
||
|
||
//字体设置(新窗口通过转盘选择) 大项目,把颜色,大小,字体等相关操作都融入进去
|
||
//Ui::Fontch* fontch = new Ui::Fontch();
|
||
//QWidget* fontset = new QWidget();
|
||
//不能多次删改一个Widget
|
||
//fontch->setupUi(fontset);
|
||
QObject::connect(uu->actionFont,&QAction::triggered,M,[&](){
|
||
QDialog* fontset = new QDialog();
|
||
// 字体选择
|
||
QFontComboBox *fontCombo = new QFontComboBox(fontset);
|
||
|
||
// 字号选择
|
||
QSpinBox *sizeSpin = new QSpinBox(fontset);
|
||
sizeSpin->setRange(6, 72);
|
||
sizeSpin->setValue(16);
|
||
|
||
// 加粗、斜体
|
||
QCheckBox *boldCheck = new QCheckBox("加粗", fontset);
|
||
QCheckBox *italicCheck = new QCheckBox("斜体", fontset);
|
||
|
||
// 颜色选择按钮
|
||
QPushButton *colorBtn = new QPushButton("选择颜色", fontset);
|
||
QColor currentColor = Qt::black;
|
||
|
||
// 示例展示标签
|
||
QLabel *previewLabel = new QLabel("字体预览", fontset);
|
||
previewLabel->setMinimumHeight(40);
|
||
previewLabel->setAlignment(Qt::AlignCenter);
|
||
|
||
// 更新样式的函数
|
||
auto updatePreview = [=, ¤tColor]() mutable {
|
||
QFont font(fontCombo->currentFont());
|
||
font.setPointSize(sizeSpin->value());
|
||
font.setBold(boldCheck->isChecked());
|
||
font.setItalic(italicCheck->isChecked());
|
||
previewLabel->setFont(font);
|
||
QPalette pal = previewLabel->palette();
|
||
pal.setColor(QPalette::WindowText, currentColor);
|
||
previewLabel->setPalette(pal);
|
||
qDebug() << "ReNewed" << Qt::endl;
|
||
};
|
||
|
||
// 响应颜色按钮点击
|
||
QObject::connect(colorBtn, &QPushButton::clicked, fontset, [=, ¤tColor]() mutable {
|
||
QColor color = QColorDialog::getColor(currentColor, fontset, "选择颜色");
|
||
if (color.isValid()) {
|
||
currentColor = color;
|
||
updatePreview();
|
||
}
|
||
});
|
||
|
||
// 连接所有变化信号
|
||
QObject::connect(fontCombo, &QFontComboBox::currentFontChanged, fontset, updatePreview);
|
||
QObject::connect(sizeSpin, QOverload<int>::of(&QSpinBox::valueChanged), fontset, updatePreview);
|
||
QObject::connect(boldCheck, &QCheckBox::toggled, fontset, updatePreview);
|
||
QObject::connect(italicCheck, &QCheckBox::toggled, fontset, updatePreview);
|
||
|
||
//确定修改按钮
|
||
QDialogButtonBox *buttonBoxs = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, fontset);
|
||
QObject::connect(buttonBoxs, &QDialogButtonBox::accepted, fontset, [=]() {
|
||
QFont finalFont = fontCombo->currentFont();
|
||
finalFont.setPointSize(sizeSpin->value());
|
||
finalFont.setBold(boldCheck->isChecked());
|
||
finalFont.setItalic(italicCheck->isChecked());
|
||
editor->setFont(finalFont);
|
||
|
||
QPalette pal = editor->palette();
|
||
pal.setColor(QPalette::Text, currentColor); // 注意你用的是 currentColor
|
||
editor->setPalette(pal);
|
||
|
||
fontset->close();
|
||
});
|
||
|
||
|
||
// 布局整理
|
||
QGridLayout *layout = new QGridLayout;
|
||
layout->addWidget(new QLabel("字体:"), 0, 0);
|
||
layout->addWidget(fontCombo, 0, 1);
|
||
layout->addWidget(new QLabel("大小:"), 1, 0);
|
||
layout->addWidget(sizeSpin, 1, 1);
|
||
layout->addWidget(new QLabel("颜色:"), 2, 0);
|
||
layout->addWidget(colorBtn, 2, 1, 1, 1);
|
||
layout->addWidget(boldCheck, 3, 1);
|
||
layout->addWidget(italicCheck, 3, 2);
|
||
layout->addWidget(previewLabel, 4, 0, 1, 2);
|
||
layout->addWidget(buttonBoxs, 5, 0);
|
||
// 你可以把 layout 放到设置页或主窗口中的某个容器里,比如:
|
||
fontset->setLayout(layout);
|
||
fontset->exec();
|
||
});
|
||
|
||
//主页面
|
||
QSplitter* mainsp = new QSplitter();
|
||
mainsp->addWidget(tree);
|
||
mainsp->addWidget(editor);
|
||
M->setCentralWidget(mainsp);
|
||
//qDebug() << "第一处" << mainsp->sizes() << Qt::endl;
|
||
//mainsp->setSizes({2,8});
|
||
//↑这里不能设置,窗口还没有初始化
|
||
|
||
|
||
//关于部分的窗口设置
|
||
QWidget* aboutq = new QWidget();
|
||
|
||
//关于-声明
|
||
Ui::about* about;
|
||
about = new Ui::about;
|
||
about->setupUi(aboutq);
|
||
QObject::connect(
|
||
uu->actionStatement,
|
||
&QAction::triggered,
|
||
M,
|
||
[&]{
|
||
|
||
about->label->setText("<h3>请认真阅读下列文字,阅读后点击“我已阅读”");
|
||
aboutq->setWindowTitle("声明");
|
||
aboutq->show();
|
||
}
|
||
);
|
||
|
||
QObject::connect(
|
||
about->button,
|
||
&QPushButton::clicked,
|
||
M,
|
||
[&]{
|
||
aboutq->close();
|
||
}
|
||
);
|
||
|
||
//关于-信息
|
||
Ui::information* info = new Ui::information();
|
||
QWidget* abouti = new QWidget();
|
||
info->setupUi(abouti);
|
||
QObject::connect(
|
||
uu->actionInformation,
|
||
&QAction::triggered,
|
||
M,
|
||
[&]{
|
||
abouti->setWindowTitle("信息-Version1.0");
|
||
abouti->show();
|
||
}
|
||
);
|
||
|
||
QObject::connect(
|
||
info->button,
|
||
&QPushButton::clicked,
|
||
M,
|
||
[&]{
|
||
abouti->close();
|
||
}
|
||
);
|
||
//关于-联系
|
||
QObject::connect(
|
||
uu->actionHuajishe,
|
||
&QAction::triggered,
|
||
M,
|
||
[&]{
|
||
QDesktopServices::openUrl(QUrl("https://huajishe.fun"));
|
||
}
|
||
);
|
||
QObject::connect(
|
||
uu->actione2hang,
|
||
&QAction::triggered,
|
||
M,
|
||
[&]{
|
||
QDesktopServices::openUrl(QUrl("https://huajishe.fun/forum"));
|
||
}
|
||
);
|
||
|
||
|
||
//关于-查看进度
|
||
QObject::connect(
|
||
uu->actiontutorial,
|
||
&QAction::triggered,
|
||
M,
|
||
[&]{
|
||
QDesktopServices::openUrl(QUrl("https://huajishe.fun/help"));
|
||
}
|
||
);
|
||
|
||
//附加参数的启动方式
|
||
|
||
// 默认最大化
|
||
bool modeSet = false;
|
||
|
||
// 检查参数
|
||
for (int i = 1; i < argc - 1; ++i) {
|
||
QString arg = argv[i];
|
||
if (arg == "-window") {
|
||
QString mode = argv[i + 1];
|
||
if (mode == "f") {
|
||
M->showFullScreen();
|
||
modeSet = true;
|
||
} else if (mode == "m") {
|
||
M->showMaximized();
|
||
modeSet = true;
|
||
} else if (mode == "s") {
|
||
M->show(); // 正常窗口
|
||
modeSet = true;
|
||
}
|
||
break; // 找到 -window 后只处理一次
|
||
}
|
||
}
|
||
|
||
if (!modeSet) {
|
||
M->showMaximized(); // 默认最大化
|
||
}
|
||
//qDebug() << "第二处" << mainsp->sizes() << Qt::endl;
|
||
int mwt, mwe;
|
||
mwt = M->width() * 0.2;
|
||
mwe = M->width() * 0.8;
|
||
mainsp->setSizes({ mwt , mwe });
|
||
|
||
qDebug() << "Success" << Qt::endl;
|
||
return app.exec();
|
||
}
|