初始化:图形化界面骨架(文件选择、语法高亮、自动缩进、查找/替换)
This commit is contained in:
31
CMakeLists.txt
Normal file
31
CMakeLists.txt
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
cmake_minimum_required(VERSION 4.0)
|
||||||
|
project(Compiler_GUI)
|
||||||
|
|
||||||
|
set(CMAKE_CXX_STANDARD 20)
|
||||||
|
set(CMAKE_AUTOMOC ON)
|
||||||
|
set(CMAKE_AUTORCC ON)
|
||||||
|
set(CMAKE_AUTOUIC ON)
|
||||||
|
|
||||||
|
set(CMAKE_PREFIX_PATH "/opt/homebrew/Cellar/qt/6.9.3")
|
||||||
|
|
||||||
|
find_package(Qt6 COMPONENTS
|
||||||
|
Core
|
||||||
|
Gui
|
||||||
|
Widgets
|
||||||
|
REQUIRED)
|
||||||
|
|
||||||
|
add_executable(Compiler_GUI main.cpp
|
||||||
|
mainwindow.cpp
|
||||||
|
mainwindow.h
|
||||||
|
ui/filebrowserwidget.cpp
|
||||||
|
ui/filebrowserwidget.h
|
||||||
|
ui/codeeditorwidget.cpp
|
||||||
|
ui/codeeditorwidget.h
|
||||||
|
backend/compileprocessmanager.cpp
|
||||||
|
backend/compileprocessmanager.h)
|
||||||
|
target_link_libraries(Compiler_GUI
|
||||||
|
Qt::Core
|
||||||
|
Qt::Gui
|
||||||
|
Qt::Widgets
|
||||||
|
)
|
||||||
|
|
||||||
51
backend/compileprocessmanager.cpp
Normal file
51
backend/compileprocessmanager.cpp
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
#include "compileprocessmanager.h"
|
||||||
|
|
||||||
|
#include <QProcess>
|
||||||
|
|
||||||
|
CompileProcessManager::CompileProcessManager(QObject *parent)
|
||||||
|
: QObject(parent)
|
||||||
|
{
|
||||||
|
m_process = new QProcess(this);
|
||||||
|
connect(m_process, &QProcess::finished,
|
||||||
|
this, &CompileProcessManager::onProcessFinished);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CompileProcessManager::runCompile(const QString &sourceCode)
|
||||||
|
{
|
||||||
|
if (m_process->state() != QProcess::NotRunning) {
|
||||||
|
// 简单处理:如果已经在运行,就先杀掉,或直接返回
|
||||||
|
m_process->kill();
|
||||||
|
m_process->waitForFinished();
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: 这里根据你的编译器协议生成指令和参数
|
||||||
|
// 假设你已存在一个后端可执行文件 "my_compiler_backend"
|
||||||
|
QString program = "my_compiler_backend";
|
||||||
|
|
||||||
|
QStringList args = buildArguments(sourceCode);
|
||||||
|
|
||||||
|
m_process->setProgram(program);
|
||||||
|
m_process->setArguments(args);
|
||||||
|
m_process->start();
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList CompileProcessManager::buildArguments(const QString &sourceCode)
|
||||||
|
{
|
||||||
|
QStringList args;
|
||||||
|
|
||||||
|
// TODO: 把 sourceCode 写入临时文件 / 管道 / 特定协议
|
||||||
|
// 这里只是示例:假设后端接受一个 -code "xxx" 的参数
|
||||||
|
args << "-code" << sourceCode;
|
||||||
|
|
||||||
|
return args;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CompileProcessManager::onProcessFinished(int exitCode, QProcess::ExitStatus status)
|
||||||
|
{
|
||||||
|
Q_UNUSED(status);
|
||||||
|
|
||||||
|
QString stdoutText = QString::fromLocal8Bit(m_process->readAllStandardOutput());
|
||||||
|
QString stderrText = QString::fromLocal8Bit(m_process->readAllStandardError());
|
||||||
|
|
||||||
|
emit compileFinished(stdoutText, stderrText, exitCode);
|
||||||
|
}
|
||||||
27
backend/compileprocessmanager.h
Normal file
27
backend/compileprocessmanager.h
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QProcess> // ✅ 关键:要完整引入 QProcess
|
||||||
|
|
||||||
|
class CompileProcessManager : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit CompileProcessManager(QObject *parent = nullptr);
|
||||||
|
|
||||||
|
// 目前简单接受代码字符串,后面可以加更多参数
|
||||||
|
void runCompile(const QString &sourceCode);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void compileFinished(const QString &stdoutText,
|
||||||
|
const QString &stderrText,
|
||||||
|
int exitCode);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void onProcessFinished(int exitCode, QProcess::ExitStatus status);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QProcess *m_process = nullptr;
|
||||||
|
|
||||||
|
QStringList buildArguments(const QString &sourceCode);
|
||||||
|
};
|
||||||
12
main.cpp
Normal file
12
main.cpp
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
#include <QApplication>
|
||||||
|
#include "mainwindow.h"
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
QApplication a(argc, argv);
|
||||||
|
|
||||||
|
MainWindow w;
|
||||||
|
w.show();
|
||||||
|
|
||||||
|
return a.exec();
|
||||||
|
}
|
||||||
175
mainwindow.cpp
Normal file
175
mainwindow.cpp
Normal file
@@ -0,0 +1,175 @@
|
|||||||
|
#include "mainwindow.h"
|
||||||
|
|
||||||
|
#include <QMenuBar>
|
||||||
|
#include <QMenu>
|
||||||
|
#include <QAction>
|
||||||
|
#include <QSplitter>
|
||||||
|
#include <QMessageBox>
|
||||||
|
#include <QFileDialog>
|
||||||
|
|
||||||
|
#include "ui/filebrowserwidget.h"
|
||||||
|
#include "ui/codeeditorwidget.h"
|
||||||
|
#include "backend/compileprocessmanager.h"
|
||||||
|
|
||||||
|
MainWindow::MainWindow(QWidget *parent)
|
||||||
|
: QMainWindow(parent)
|
||||||
|
{
|
||||||
|
createActions();
|
||||||
|
createMenus();
|
||||||
|
setupCentralWidgets();
|
||||||
|
|
||||||
|
m_compileManager = new CompileProcessManager(this);
|
||||||
|
|
||||||
|
connectSignals();
|
||||||
|
|
||||||
|
setWindowTitle(tr("My Compiler IDE"));
|
||||||
|
resize(1200, 800);
|
||||||
|
}
|
||||||
|
|
||||||
|
MainWindow::~MainWindow()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::createActions()
|
||||||
|
{
|
||||||
|
// File
|
||||||
|
m_actNew = new QAction(tr("&New"), this);
|
||||||
|
m_actOpen = new QAction(tr("&Open..."), this);
|
||||||
|
m_actSave = new QAction(tr("&Save"), this);
|
||||||
|
m_actExit = new QAction(tr("E&xit"), this);
|
||||||
|
|
||||||
|
// Build / Run
|
||||||
|
m_actBuild = new QAction(tr("&Build"), this);
|
||||||
|
m_actRun = new QAction(tr("&Run"), this);
|
||||||
|
|
||||||
|
// 可以设置快捷键
|
||||||
|
m_actNew->setShortcut(QKeySequence::New);
|
||||||
|
m_actOpen->setShortcut(QKeySequence::Open);
|
||||||
|
m_actSave->setShortcut(QKeySequence::Save);
|
||||||
|
m_actExit->setShortcut(QKeySequence::Quit);
|
||||||
|
|
||||||
|
m_actBuild->setShortcut(Qt::Key_F5);
|
||||||
|
m_actRun->setShortcut(Qt::Key_F6);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::createMenus()
|
||||||
|
{
|
||||||
|
// File 菜单
|
||||||
|
QMenu *fileMenu = menuBar()->addMenu(tr("&File"));
|
||||||
|
fileMenu->addAction(m_actNew);
|
||||||
|
fileMenu->addAction(m_actOpen);
|
||||||
|
fileMenu->addAction(m_actSave);
|
||||||
|
fileMenu->addSeparator();
|
||||||
|
fileMenu->addAction(m_actExit);
|
||||||
|
|
||||||
|
// Edit 菜单(先占位,之后可以加撤销/重做/查找等)
|
||||||
|
QMenu *editMenu = menuBar()->addMenu(tr("&Edit"));
|
||||||
|
Q_UNUSED(editMenu);
|
||||||
|
|
||||||
|
// Build 菜单
|
||||||
|
QMenu *buildMenu = menuBar()->addMenu(tr("&Build"));
|
||||||
|
buildMenu->addAction(m_actBuild);
|
||||||
|
buildMenu->addAction(m_actRun);
|
||||||
|
|
||||||
|
// Help 菜单(占位)
|
||||||
|
QMenu *helpMenu = menuBar()->addMenu(tr("&Help"));
|
||||||
|
Q_UNUSED(helpMenu);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::setupCentralWidgets()
|
||||||
|
{
|
||||||
|
// 左右分割:左文件列表、右代码编辑区
|
||||||
|
QSplitter *splitter = new QSplitter(Qt::Horizontal, this);
|
||||||
|
|
||||||
|
m_fileBrowser = new FileBrowserWidget(splitter);
|
||||||
|
m_codeEditor = new CodeEditorWidget(splitter);
|
||||||
|
|
||||||
|
splitter->setStretchFactor(0, 1); // 文件列表
|
||||||
|
splitter->setStretchFactor(1, 3); // 代码编辑
|
||||||
|
|
||||||
|
setCentralWidget(splitter);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::connectSignals()
|
||||||
|
{
|
||||||
|
// 菜单动作
|
||||||
|
connect(m_actNew, &QAction::triggered, this, &MainWindow::onActionNewFile);
|
||||||
|
connect(m_actOpen, &QAction::triggered, this, &MainWindow::onActionOpenFile);
|
||||||
|
connect(m_actSave, &QAction::triggered, this, &MainWindow::onActionSaveFile);
|
||||||
|
connect(m_actExit, &QAction::triggered, this, &MainWindow::onActionExit);
|
||||||
|
|
||||||
|
connect(m_actBuild, &QAction::triggered, this, &MainWindow::onActionBuild);
|
||||||
|
connect(m_actRun, &QAction::triggered, this, &MainWindow::onActionRun);
|
||||||
|
|
||||||
|
// 编译完成信号
|
||||||
|
connect(m_compileManager, &CompileProcessManager::compileFinished,
|
||||||
|
this, &MainWindow::onCompileFinished);
|
||||||
|
|
||||||
|
// 文件列表点击打开文件(后面可以在 FileBrowserWidget 里发信号)
|
||||||
|
connect(m_fileBrowser, &FileBrowserWidget::fileOpenRequested,
|
||||||
|
m_codeEditor, &CodeEditorWidget::loadFromFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ========== 菜单槽函数(先简单占位) ==========
|
||||||
|
|
||||||
|
void MainWindow::onActionNewFile()
|
||||||
|
{
|
||||||
|
m_codeEditor->clearEditor();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::onActionOpenFile()
|
||||||
|
{
|
||||||
|
QString filePath = QFileDialog::getOpenFileName(this, tr("Open File"));
|
||||||
|
if (filePath.isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_codeEditor->loadFromFile(filePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::onActionSaveFile()
|
||||||
|
{
|
||||||
|
// 简单实现:如果 CodeEditor 里自己记录了当前文件路径,就直接保存
|
||||||
|
// 否则先弹出另存为。这里先调用一个占位接口,具体实现之后我们再做。
|
||||||
|
if (!m_codeEditor->save())
|
||||||
|
{
|
||||||
|
QString filePath = QFileDialog::getSaveFileName(this, tr("Save File"));
|
||||||
|
if (!filePath.isEmpty())
|
||||||
|
{
|
||||||
|
m_codeEditor->saveAs(filePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::onActionExit()
|
||||||
|
{
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::onActionBuild()
|
||||||
|
{
|
||||||
|
// 获取当前编辑器中的代码文本
|
||||||
|
QString code = m_codeEditor->currentText();
|
||||||
|
|
||||||
|
// TODO: 这里可以根据 code / 当前选中的编译选项,生成指令、参数等
|
||||||
|
// 目前先简单把 code 直接发给后端,后面你告诉我后端协议,我们再细化
|
||||||
|
m_compileManager->runCompile(code);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::onActionRun()
|
||||||
|
{
|
||||||
|
// TODO: 之后可以根据编译结果调用可执行文件运行,或者编译+运行
|
||||||
|
QMessageBox::information(this, tr("Run"), tr("Run action triggered (TODO)."));
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::onCompileFinished(const QString &stdoutText,
|
||||||
|
const QString &stderrText,
|
||||||
|
int exitCode)
|
||||||
|
{
|
||||||
|
// 这里先简单弹个窗口,后面我们可以加“底部控制台”面板输出
|
||||||
|
QString msg = tr("Exit code: %1\n\nSTDOUT:\n%2\n\nSTDERR:\n%3")
|
||||||
|
.arg(exitCode)
|
||||||
|
.arg(stdoutText)
|
||||||
|
.arg(stderrText);
|
||||||
|
|
||||||
|
QMessageBox::information(this, tr("Build Result"), msg);
|
||||||
|
}
|
||||||
53
mainwindow.h
Normal file
53
mainwindow.h
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QMainWindow>
|
||||||
|
|
||||||
|
class FileBrowserWidget;
|
||||||
|
class CodeEditorWidget;
|
||||||
|
class CompileProcessManager;
|
||||||
|
|
||||||
|
class MainWindow : public QMainWindow
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit MainWindow(QWidget *parent = nullptr);
|
||||||
|
~MainWindow();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void onActionNewFile();
|
||||||
|
void onActionOpenFile();
|
||||||
|
void onActionSaveFile();
|
||||||
|
void onActionExit();
|
||||||
|
|
||||||
|
void onActionBuild();
|
||||||
|
void onActionRun();
|
||||||
|
|
||||||
|
// 后端编译结果回调
|
||||||
|
void onCompileFinished(const QString &stdoutText,
|
||||||
|
const QString &stderrText,
|
||||||
|
int exitCode);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void createActions();
|
||||||
|
void createMenus();
|
||||||
|
void setupCentralWidgets();
|
||||||
|
void connectSignals();
|
||||||
|
|
||||||
|
private:
|
||||||
|
// UI 部件
|
||||||
|
FileBrowserWidget *m_fileBrowser = nullptr;
|
||||||
|
CodeEditorWidget *m_codeEditor = nullptr;
|
||||||
|
|
||||||
|
// 后端模块
|
||||||
|
CompileProcessManager *m_compileManager = nullptr;
|
||||||
|
|
||||||
|
// 菜单动作
|
||||||
|
QAction *m_actNew = nullptr;
|
||||||
|
QAction *m_actOpen = nullptr;
|
||||||
|
QAction *m_actSave = nullptr;
|
||||||
|
QAction *m_actExit = nullptr;
|
||||||
|
|
||||||
|
QAction *m_actBuild = nullptr;
|
||||||
|
QAction *m_actRun = nullptr;
|
||||||
|
};
|
||||||
1305
ui/codeeditorwidget.cpp
Normal file
1305
ui/codeeditorwidget.cpp
Normal file
File diff suppressed because it is too large
Load Diff
132
ui/codeeditorwidget.h
Normal file
132
ui/codeeditorwidget.h
Normal file
@@ -0,0 +1,132 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QWidget>
|
||||||
|
#include <QPlainTextEdit>
|
||||||
|
#include <QColor>
|
||||||
|
#include <QHash>
|
||||||
|
#include <QVector>
|
||||||
|
#include <QSet>
|
||||||
|
#include <QStringList>
|
||||||
|
#include <QTextCursor>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class LineNumberArea;
|
||||||
|
class CSyntaxHighlighter;
|
||||||
|
class CompletionPopup;
|
||||||
|
class FindReplaceBar;
|
||||||
|
|
||||||
|
// 每个字符的背景信息
|
||||||
|
struct CharBackgroundInfo
|
||||||
|
{
|
||||||
|
int column = 0; // 这一行中的列号(从 0 开始)
|
||||||
|
QColor color;
|
||||||
|
qreal alpha = 1.0; // 0.0 ~ 1.0
|
||||||
|
};
|
||||||
|
|
||||||
|
// 每一行的背景信息
|
||||||
|
struct LineBackgroundInfo
|
||||||
|
{
|
||||||
|
QColor color;
|
||||||
|
qreal alpha = 1.0; // 0.0 ~ 1.0
|
||||||
|
};
|
||||||
|
|
||||||
|
// 真正的代码编辑器,继承 QPlainTextEdit
|
||||||
|
class CodeEditor : public QPlainTextEdit
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit CodeEditor(QWidget *parent = nullptr);
|
||||||
|
|
||||||
|
int lineNumberAreaWidth() const;
|
||||||
|
|
||||||
|
// 预留接口:设置行/字符背景(带透明度)
|
||||||
|
void setLineBackground(int line, const QColor &color, qreal alpha = 1.0);
|
||||||
|
void clearLineBackground(int line);
|
||||||
|
void clearAllLineBackgrounds();
|
||||||
|
|
||||||
|
void setCharBackground(int line, int column, const QColor &color, qreal alpha = 1.0);
|
||||||
|
void clearCharBackground(int line, int column);
|
||||||
|
void clearAllCharBackgrounds();
|
||||||
|
|
||||||
|
// 行号区域的绘制 & 点击
|
||||||
|
void lineNumberAreaPaintEvent(QPaintEvent *event);
|
||||||
|
void lineNumberAreaMousePressEvent(QMouseEvent *event);
|
||||||
|
|
||||||
|
void searchNext(const QString &text);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
// 断点状态变化(暂时只发信号,不做具体逻辑)
|
||||||
|
void breakpointToggled(int line, bool enabled);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void resizeEvent(QResizeEvent *event) override;
|
||||||
|
void keyPressEvent(QKeyEvent *event) override;
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void updateLineNumberAreaWidth(int newBlockCount);
|
||||||
|
void updateLineNumberArea(const QRect &rect, int dy);
|
||||||
|
void highlightCurrentLine();
|
||||||
|
|
||||||
|
// ✅ 新增:来自联想窗口的补全插入
|
||||||
|
void insertCompletion(const QString &completion);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void refreshExtraSelections();
|
||||||
|
void handleReturnKey(QKeyEvent *event);
|
||||||
|
void toggleBreakpoint(int line);
|
||||||
|
|
||||||
|
// ✅ 新增:联想相关辅助函数
|
||||||
|
void initCompletion();
|
||||||
|
void showCompletion(const QString &prefix);
|
||||||
|
void hideCompletion();
|
||||||
|
QString wordUnderCursor() const;
|
||||||
|
void rebuildSearchMatches();
|
||||||
|
void applySearchHighlights();
|
||||||
|
|
||||||
|
private:
|
||||||
|
LineNumberArea *m_lineNumberArea = nullptr;
|
||||||
|
CSyntaxHighlighter *m_highlighter = nullptr;
|
||||||
|
|
||||||
|
QSet<int> m_breakpoints;
|
||||||
|
|
||||||
|
QHash<int, LineBackgroundInfo> m_lineBackgrounds;
|
||||||
|
QHash<int, QVector<CharBackgroundInfo>> m_charBackgrounds;
|
||||||
|
|
||||||
|
// ✅ 新增:联想窗口和候选词列表
|
||||||
|
CompletionPopup *m_completionPopup = nullptr;
|
||||||
|
QStringList m_completionWords;
|
||||||
|
|
||||||
|
QString m_searchText;
|
||||||
|
QVector<QTextCursor> m_searchMatches;
|
||||||
|
int m_currentMatchIndex = -1;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// 对外仍然叫 CodeEditorWidget,内部包一个 CodeEditor
|
||||||
|
class CodeEditorWidget : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit CodeEditorWidget(QWidget *parent = nullptr);
|
||||||
|
|
||||||
|
void loadFromFile(const QString &filePath);
|
||||||
|
bool save();
|
||||||
|
bool saveAs(const QString &filePath);
|
||||||
|
|
||||||
|
QString currentText() const;
|
||||||
|
void clearEditor();
|
||||||
|
|
||||||
|
// 代理到内部 CodeEditor 的接口(以后你可以直接拿来做可视化用)
|
||||||
|
void setLineBackground(int line, const QColor &color, qreal alpha = 1.0);
|
||||||
|
void clearLineBackground(int line);
|
||||||
|
|
||||||
|
void setCharBackground(int line, int column, const QColor &color, qreal alpha = 1.0);
|
||||||
|
void clearCharBackground(int line, int column);
|
||||||
|
|
||||||
|
private:
|
||||||
|
CodeEditor *m_editor = nullptr;
|
||||||
|
QString m_currentFilePath;
|
||||||
|
FindReplaceBar *m_findBar = nullptr;
|
||||||
|
};
|
||||||
51
ui/filebrowserwidget.cpp
Normal file
51
ui/filebrowserwidget.cpp
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
#include "filebrowserwidget.h"
|
||||||
|
|
||||||
|
#include <QTreeView>
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
#include <QDir>
|
||||||
|
|
||||||
|
FileBrowserWidget::FileBrowserWidget(QWidget *parent)
|
||||||
|
: QWidget(parent)
|
||||||
|
{
|
||||||
|
setupUi();
|
||||||
|
connectSignals();
|
||||||
|
|
||||||
|
// 默认浏览当前工作目录
|
||||||
|
setRootPath(QDir::currentPath());
|
||||||
|
}
|
||||||
|
|
||||||
|
void FileBrowserWidget::setupUi()
|
||||||
|
{
|
||||||
|
m_model = new QFileSystemModel(this);
|
||||||
|
m_model->setRootPath(QString()); // 稍后在 setRootPath 里设置
|
||||||
|
|
||||||
|
m_view = new QTreeView(this);
|
||||||
|
m_view->setModel(m_model);
|
||||||
|
m_view->setHeaderHidden(true);
|
||||||
|
m_view->setAnimated(true);
|
||||||
|
|
||||||
|
auto *layout = new QVBoxLayout(this);
|
||||||
|
layout->setContentsMargins(0, 0, 0, 0);
|
||||||
|
layout->addWidget(m_view);
|
||||||
|
setLayout(layout);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FileBrowserWidget::connectSignals()
|
||||||
|
{
|
||||||
|
connect(m_view, &QTreeView::doubleClicked,
|
||||||
|
this, [this](const QModelIndex &index) {
|
||||||
|
if (!m_model)
|
||||||
|
return;
|
||||||
|
QString path = m_model->filePath(index);
|
||||||
|
if (QFileInfo(path).isFile())
|
||||||
|
emit fileOpenRequested(path);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void FileBrowserWidget::setRootPath(const QString &path)
|
||||||
|
{
|
||||||
|
if (!m_model)
|
||||||
|
return;
|
||||||
|
QModelIndex idx = m_model->setRootPath(path);
|
||||||
|
m_view->setRootIndex(idx);
|
||||||
|
}
|
||||||
26
ui/filebrowserwidget.h
Normal file
26
ui/filebrowserwidget.h
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QWidget>
|
||||||
|
#include <QFileSystemModel>
|
||||||
|
|
||||||
|
class QTreeView;
|
||||||
|
|
||||||
|
class FileBrowserWidget : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit FileBrowserWidget(QWidget *parent = nullptr);
|
||||||
|
|
||||||
|
void setRootPath(const QString &path);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
// 当用户双击或选择某个文件时,通知 MainWindow/CodeEditor 打开
|
||||||
|
void fileOpenRequested(const QString &filePath);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QFileSystemModel *m_model = nullptr;
|
||||||
|
QTreeView *m_view = nullptr;
|
||||||
|
|
||||||
|
void setupUi();
|
||||||
|
void connectSignals();
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user