├── .gitattributes ├── .gitignore ├── LICENSE ├── README.md ├── preview └── 23333.gif └── src ├── MainApps ├── MainApps.pro └── QtAddressBar │ ├── AddressItem.cpp │ ├── AddressItem.h │ ├── FileSystemModel.cpp │ ├── FileSystemModel.h │ ├── MainWindow.cpp │ ├── MainWindow.h │ ├── MainWindow.ui │ ├── MenuWidget.cpp │ ├── MenuWidget.h │ ├── MenuWidget.ui │ ├── NoFocusRectStyle.h │ ├── QtAddressBar.cpp │ ├── QtAddressBar.h │ ├── QtAddressBar.pro │ ├── main.cpp │ ├── res.qrc │ └── res │ ├── arrow_back.png │ ├── arrow_down.png │ ├── arrow_right.png │ └── dir.png ├── Path.pri └── QtAddressBar.pro /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # ignore user files 2 | *.user 3 | *.autosave 4 | .DS_Store 5 | 6 | # 忽略生成的中间文件 7 | 8 | **build** 9 | Intermediate/ 10 | RunImage/ 11 | 12 | # 忽略一些草稿文件 13 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 longxr 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # QtAddressBar 2 | windows address bar by Qt 3 | 4 | # ScreenShot 5 | ![效果图](preview/23333.gif) 6 | -------------------------------------------------------------------------------- /preview/23333.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Longxr/QtAddressBar/7b2103658cc1744f5bc75a06fbd964366854b20a/preview/23333.gif -------------------------------------------------------------------------------- /src/MainApps/MainApps.pro: -------------------------------------------------------------------------------- 1 | TEMPLATE = subdirs 2 | 3 | SUBDIRS += QtAddressBar 4 | CONFIG += ordered 5 | -------------------------------------------------------------------------------- /src/MainApps/QtAddressBar/AddressItem.cpp: -------------------------------------------------------------------------------- 1 | #include "AddressItem.h" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #define ARROW_WIDTH 17 12 | #define SPACE_WIDTH 8 13 | #define ITEM_HEIGHT 20 14 | 15 | AddressItem::AddressItem(const QString &text, const QString &path, bool isRoot, QWidget *parent) : 16 | QPushButton(parent), 17 | m_pressed(false), 18 | m_pressedText(false), 19 | m_moveflag(false), 20 | m_bRoot(isRoot), 21 | m_path(path), 22 | m_text(text) 23 | { 24 | m_font = parent->font(); 25 | 26 | if(m_text.isEmpty()) { 27 | m_textWidth = 0; 28 | setFixedSize(ARROW_WIDTH, 21); 29 | } 30 | else { 31 | QFontMetrics fm(m_font); 32 | m_textWidth = fm.width(m_text) + SPACE_WIDTH; 33 | setFixedSize(m_textWidth + ARROW_WIDTH, 21); 34 | } 35 | 36 | InitUI(); 37 | } 38 | 39 | AddressItem::~AddressItem() 40 | { 41 | delete m_clickmenu; 42 | } 43 | 44 | void AddressItem::setBackIcon(bool flag) 45 | { 46 | if(flag) { 47 | m_normalIcon = QPixmap(":/res/arrow_back.png"); 48 | } 49 | else { 50 | m_normalIcon = QPixmap(":/res/arrow_right.png"); 51 | } 52 | } 53 | 54 | void AddressItem::paintEvent(QPaintEvent *) 55 | { 56 | QPainter painter(this); 57 | 58 | if (m_moveflag) 59 | { 60 | painter.setPen(QColor(205, 232, 254)); 61 | painter.fillRect(QRectF(0, 0, m_textWidth+ARROW_WIDTH, ITEM_HEIGHT), QBrush(QColor(229, 243, 254))); 62 | painter.drawRect(QRectF(0,0, m_textWidth, ITEM_HEIGHT)); 63 | painter.drawRect(QRectF(m_textWidth, 0, ARROW_WIDTH, ITEM_HEIGHT)); 64 | } 65 | 66 | if (m_pressed || isChecked()) 67 | { 68 | painter.setPen(QColor(153, 209, 255)); 69 | painter.fillRect(QRectF(0, 0, m_textWidth+ARROW_WIDTH, ITEM_HEIGHT), QBrush(QColor(204, 232, 255))); 70 | painter.drawRect(QRectF(0,0, m_textWidth, ITEM_HEIGHT)); 71 | painter.drawRect(QRectF(m_textWidth, 0, ARROW_WIDTH, ITEM_HEIGHT)); 72 | 73 | painter.setPen(QColor(0, 0, 0)); 74 | painter.setFont(m_font); 75 | painter.drawText(QRectF(1,1, m_textWidth, ITEM_HEIGHT), Qt::AlignCenter, m_text); 76 | painter.drawPixmap(QRectF(m_textWidth, 0, ARROW_WIDTH, ITEM_HEIGHT), m_checkedIcon, m_checkedIcon.rect()); 77 | } 78 | else 79 | { 80 | painter.setPen(QColor(0, 0, 0)); 81 | painter.setFont(m_font); 82 | painter.drawText(QRectF(0,0, m_textWidth, ITEM_HEIGHT), Qt::AlignCenter, m_text); 83 | painter.drawPixmap(QRectF(m_textWidth, 0, ARROW_WIDTH, ITEM_HEIGHT), m_normalIcon, m_normalIcon.rect()); 84 | } 85 | 86 | } 87 | 88 | void AddressItem::mousePressEvent(QMouseEvent *event) 89 | { 90 | if(event->button() == Qt::LeftButton && hitButton(event->pos())) { 91 | m_pressed = true; 92 | 93 | if(QRectF(0,0, m_textWidth, ITEM_HEIGHT).contains(event->pos())){ 94 | m_pressedText = true; 95 | 96 | } 97 | else if(QRectF(m_textWidth, 0, ARROW_WIDTH, ITEM_HEIGHT).contains(event->pos())) { 98 | // setChecked(!isChecked()); 99 | update(); 100 | return QPushButton::mousePressEvent(event); 101 | } 102 | 103 | update(); 104 | } 105 | } 106 | 107 | void AddressItem::mouseReleaseEvent(QMouseEvent *event) 108 | { 109 | if(event->button() == Qt::LeftButton){ 110 | if(m_pressedText) { 111 | qDebug() << "clicked item"; 112 | emit SClickPath(m_path); 113 | } 114 | 115 | m_pressedText = false; 116 | m_pressed = false; 117 | 118 | update(); 119 | 120 | return QPushButton::mouseReleaseEvent(event); 121 | } 122 | } 123 | 124 | //void AddressItem::mouseMoveEvent(QMouseEvent *event) 125 | //{ 126 | // if(hitButton(event->pos())) { 127 | // m_moveflag = true; 128 | // } 129 | // update(); 130 | //} 131 | 132 | void AddressItem::enterEvent(QEvent *) 133 | { 134 | m_moveflag = true; 135 | update(); 136 | } 137 | 138 | void AddressItem::leaveEvent(QEvent *) 139 | { 140 | m_moveflag = false; 141 | // m_clickmenu->hide(); 142 | update(); 143 | } 144 | 145 | void AddressItem::menuAboutToHide() 146 | { 147 | m_moveflag = false; 148 | m_pressed = false; 149 | } 150 | 151 | void AddressItem::onClickMenuItem() 152 | { 153 | QAction *action = qobject_cast(sender()); 154 | QString actionPath = m_path + action->text(); 155 | 156 | qDebug() << "clicked menu"; 157 | emit SClickPath(actionPath); 158 | } 159 | 160 | void AddressItem::onCheckChanged(bool checked) 161 | { 162 | update(); 163 | 164 | if (checked) 165 | { 166 | if(!m_clickmenu->isVisible()) { 167 | QPoint GlobalPoint(this->mapToGlobal(QPoint(0,0))); 168 | GlobalPoint.setX(GlobalPoint.x() + ARROW_WIDTH+m_textWidth - 30); 169 | GlobalPoint.setY(GlobalPoint.y() + ITEM_HEIGHT); 170 | m_clickmenu->move(GlobalPoint); 171 | //menu->move(cursor().pos()); 172 | m_clickmenu->show(); 173 | } 174 | } 175 | else{ 176 | m_clickmenu->close(); 177 | } 178 | } 179 | 180 | void AddressItem::InitUI() 181 | { 182 | m_normalIcon = QPixmap(":/res/arrow_right.png"); 183 | m_checkedIcon = QPixmap(":/res/arrow_down.png"); 184 | 185 | m_clickmenu = new QMenu(this); 186 | m_clickmenu->setWindowFlags(Qt::ToolTip); 187 | // setAttribute(Qt::WA_TransparentForMouseEvents); 188 | connect(m_clickmenu, SIGNAL(aboutToHide()), this, SLOT(menuAboutToHide())); 189 | 190 | QWidgetAction* action = new QWidgetAction(this); 191 | m_pMenuWidget = new MenuWidget(m_bRoot, this); 192 | m_pMenuWidget->updateDirModel(m_path); 193 | action->setDefaultWidget(m_pMenuWidget); 194 | m_clickmenu->addAction(action); 195 | 196 | m_clickmenu->setStyleSheet("QMenu {background-color:rgb(242,242,242); border: 1px solid rgb(100,100,100);}\ 197 | QMenu::item {font-size: 9pt; color: rgb(0,0,0); padding:4px 20px 4px 20px;margin:1px 2px;}\ 198 | QMenu::item:selected { background-color:rgb(196,222,244);}"); 199 | 200 | setMouseTracking(true); 201 | setCheckable(true); 202 | 203 | connect(this, &AddressItem::toggled, this, &AddressItem::onCheckChanged); 204 | connect(m_pMenuWidget, &MenuWidget::SClickPath, this, &AddressItem::SClickPath); 205 | } 206 | -------------------------------------------------------------------------------- /src/MainApps/QtAddressBar/AddressItem.h: -------------------------------------------------------------------------------- 1 | #ifndef ADDRESSITEM_H 2 | #define ADDRESSITEM_H 3 | 4 | #include 5 | #include 6 | 7 | #include "MenuWidget.h" 8 | 9 | class AddressItem : public QPushButton 10 | { 11 | Q_OBJECT 12 | public: 13 | explicit AddressItem(const QString &text, const QString &path, bool isRoot = true, QWidget *parent = 0); 14 | ~AddressItem(); 15 | 16 | void setBackIcon(bool flag); 17 | 18 | signals: 19 | void SClickPath(const QString &path); 20 | 21 | protected: 22 | void paintEvent(QPaintEvent *event); 23 | void mousePressEvent(QMouseEvent *event); 24 | void mouseReleaseEvent(QMouseEvent *event); 25 | // void mouseMoveEvent(QMouseEvent *event); 26 | void enterEvent(QEvent *); 27 | void leaveEvent(QEvent *); 28 | 29 | private slots: 30 | void menuAboutToHide(); 31 | void onClickMenuItem(); 32 | void onCheckChanged(bool checked); 33 | 34 | private: 35 | void InitUI(); 36 | 37 | private: 38 | bool m_pressed; 39 | bool m_pressedText; 40 | bool m_moveflag; 41 | bool m_bRoot; 42 | 43 | QMenu* m_clickmenu; 44 | MenuWidget* m_pMenuWidget; 45 | 46 | int m_textWidth; 47 | QFont m_font; 48 | 49 | QString m_path; 50 | QString m_text; 51 | 52 | QPixmap m_normalIcon; 53 | QPixmap m_checkedIcon; 54 | }; 55 | 56 | #endif // ADDRESSITEM_H 57 | -------------------------------------------------------------------------------- /src/MainApps/QtAddressBar/FileSystemModel.cpp: -------------------------------------------------------------------------------- 1 | #include "FileSystemModel.h" 2 | 3 | #include 4 | 5 | FileSystemModel::FileSystemModel(QObject *parent) : 6 | QFileSystemModel(parent) 7 | { 8 | 9 | } 10 | 11 | FileSystemModel::~FileSystemModel() 12 | { 13 | 14 | } 15 | 16 | QVariant FileSystemModel::data(const QModelIndex &index, int role) const 17 | { 18 | switch(role){ 19 | case Qt::FontRole:{ 20 | QFont font; 21 | font.setPointSize(10); 22 | font.setBold(false); 23 | return font; 24 | } 25 | 26 | case Qt::TextAlignmentRole: 27 | return QVariant(Qt::AlignLeft | Qt::AlignVCenter); 28 | 29 | default: 30 | return QFileSystemModel::data(index, role); 31 | } 32 | 33 | return QFileSystemModel::data(index, role); 34 | } 35 | -------------------------------------------------------------------------------- /src/MainApps/QtAddressBar/FileSystemModel.h: -------------------------------------------------------------------------------- 1 | #ifndef FILESYSTEMMODEL_H 2 | #define FILESYSTEMMODEL_H 3 | 4 | #include 5 | #include 6 | 7 | class FileSystemModel : public QFileSystemModel 8 | { 9 | Q_OBJECT 10 | 11 | public: 12 | explicit FileSystemModel(QObject *parent = 0); 13 | ~FileSystemModel(); 14 | 15 | virtual QVariant data(const QModelIndex &index, int role) const; 16 | // virtual bool setData(const QModelIndex &index, const QVariant &value, int role); 17 | }; 18 | 19 | #endif // FILESYSTEMMODEL_H 20 | -------------------------------------------------------------------------------- /src/MainApps/QtAddressBar/MainWindow.cpp: -------------------------------------------------------------------------------- 1 | #include "MainWindow.h" 2 | #include "ui_MainWindow.h" 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | MainWindow::MainWindow(QWidget *parent) : 9 | QMainWindow(parent), 10 | ui(new Ui::MainWindow) 11 | { 12 | ui->setupUi(this); 13 | 14 | InitUI(); 15 | 16 | 17 | } 18 | 19 | MainWindow::~MainWindow() 20 | { 21 | delete ui; 22 | } 23 | 24 | void MainWindow::slotShowChild(const QModelIndex &index) 25 | { 26 | QString path = m_pFileSystemModel->fileInfo(index).absoluteFilePath(); 27 | qDebug() << "path:" << path; 28 | 29 | if(m_pFileSystemModel->fileInfo(index).isDir()) { 30 | m_currentPath = path; 31 | ui->addressbar->UpdateCurrentPath(path); 32 | 33 | ui->tableView->setRootIndex(m_pFileSystemModel->index(m_currentPath)); 34 | ui->tableView->clearSelection(); 35 | ui->tableView->scrollToTop(); 36 | } 37 | else 38 | { 39 | #ifdef _WIN32 40 | path.replace("/","\\"); 41 | #endif 42 | QProcess::startDetached("explorer "+path); 43 | } 44 | } 45 | 46 | void MainWindow::slotSelectCurrent(const QModelIndex &index) 47 | { 48 | 49 | } 50 | 51 | void MainWindow::slotCurrentPathChanged(const QString &path) 52 | { 53 | m_currentPath = path; 54 | m_pFileSystemModel->setRootPath(m_currentPath); 55 | 56 | ui->tableView->setRootIndex(m_pFileSystemModel->index(m_currentPath)); 57 | ui->tableView->scrollToTop(); 58 | 59 | ui->addressbar->UpdateCurrentPath(path); 60 | } 61 | 62 | void MainWindow::onCompleterChoosed(const QString &path) 63 | { 64 | QString pathStr = QString(path); 65 | pathStr.replace("\\", "/"); 66 | ui->addressbar->UpdateCurrentPath(pathStr); 67 | } 68 | 69 | void MainWindow::onTextChanged(const QString &text) 70 | { 71 | int index = text.lastIndexOf("/"); 72 | QString dirStr = text.left(index + 1); 73 | // QString completeStr = text.right(text.length() - index -1); 74 | 75 | if(m_completerDir == dirStr) { 76 | return; 77 | } 78 | else{ 79 | m_completerDir = dirStr; 80 | } 81 | 82 | QFileInfo info(dirStr); 83 | if(info.isDir()) { 84 | m_pCompleterModel->refresh(m_pCompleterModel->index(dirStr)); 85 | } 86 | } 87 | 88 | void MainWindow::InitUI() 89 | { 90 | m_currentPath = QString("C:/Windows/System32/sk-SK"); 91 | m_pFileSystemModel = new FileSystemModel(this); 92 | m_pFileSystemModel->setRootPath(m_currentPath); 93 | ui->addressbar->setText(m_currentPath); 94 | 95 | ui->tableView->setModel(m_pFileSystemModel); 96 | ui->tableView->setRootIndex(m_pFileSystemModel->index(m_currentPath)); 97 | ui->tableView->scrollToTop(); 98 | ui->tableView->verticalHeader()->hide(); 99 | ui->tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); 100 | // ui->tableView->horizontalHeader()->setStretchLastSection(true); 101 | ui->tableView->setSelectionBehavior(QAbstractItemView::SelectRows); 102 | ui->tableView->setSelectionMode(QAbstractItemView::SingleSelection); 103 | ui->tableView->setEditTriggers(QAbstractItemView::NoEditTriggers); 104 | ui->tableView->setVerticalScrollMode(QAbstractItemView::ScrollPerItem); 105 | ui->tableView->setShowGrid(false); // disable the table grid. 106 | ui->tableView->verticalHeader()->setDefaultSectionSize(25); // set row height. 107 | ui->tableView->horizontalHeader()->setHighlightSections(false); 108 | ui->tableView->setFrameShape(QFrame::NoFrame); 109 | ui->tableView->installEventFilter(this); 110 | 111 | m_pCompleterModel = new QDirModel(this); 112 | m_pCompleterModel->setReadOnly(false); 113 | m_pCompleterModel->setFilter(QDir::Dirs | QDir::NoDotAndDotDot); 114 | m_pCompleter = new QCompleter(m_pCompleterModel, this); 115 | ui->addressbar->setCompleter(m_pCompleter); 116 | 117 | connect(m_pCompleter, SIGNAL(activated(const QString&)), this, SLOT(onCompleterChoosed(const QString&))); 118 | connect(ui->addressbar, SIGNAL(textChanged(const QString&)), this, SLOT(onTextChanged(const QString&))); 119 | 120 | connect(ui->tableView, &QTableView::doubleClicked, this, &MainWindow::slotShowChild); 121 | connect(ui->tableView, &QTableView::clicked, this, &MainWindow::slotSelectCurrent); 122 | 123 | connect(ui->addressbar, &QtAddressBar::SCurrentPathChanged, this, &MainWindow::slotCurrentPathChanged); 124 | } 125 | 126 | void MainWindow::on_pushButton_clicked() 127 | { 128 | m_currentPath = QString("C:/Windows/System32/sk-SK"); 129 | ui->addressbar->UpdateCurrentPath(m_currentPath); 130 | } 131 | 132 | bool MainWindow::event(QEvent *event) 133 | { 134 | // qDebug() << event->type(); 135 | 136 | if(event->type() == QEvent::NonClientAreaMouseButtonPress || event->type() == QEvent::MouseButtonPress || 137 | event->type() == QEvent::WindowDeactivate) { 138 | ui->addressbar->closeMenu(); 139 | } 140 | 141 | return QMainWindow::event(event); 142 | } 143 | 144 | bool MainWindow::eventFilter(QObject *watched, QEvent *event) 145 | { 146 | if(watched == ui->tableView) 147 | { 148 | // qDebug() << event->type(); 149 | if(event->type() == QEvent::FocusIn) 150 | { 151 | ui->addressbar->closeMenu(); 152 | } 153 | } 154 | 155 | return QMainWindow::eventFilter(watched, event); 156 | } 157 | -------------------------------------------------------------------------------- /src/MainApps/QtAddressBar/MainWindow.h: -------------------------------------------------------------------------------- 1 | #ifndef MAINWINDOW_H 2 | #define MAINWINDOW_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include "FileSystemModel.h" 9 | 10 | namespace Ui { 11 | class MainWindow; 12 | } 13 | 14 | class MainWindow : public QMainWindow 15 | { 16 | Q_OBJECT 17 | 18 | public: 19 | explicit MainWindow(QWidget *parent = 0); 20 | ~MainWindow(); 21 | 22 | private slots: 23 | void slotShowChild(const QModelIndex &index); 24 | void slotSelectCurrent(const QModelIndex &index); 25 | void slotCurrentPathChanged(const QString &path); 26 | 27 | void onCompleterChoosed(const QString&); 28 | void onTextChanged(const QString&); 29 | void on_pushButton_clicked(); 30 | 31 | protected: 32 | bool event(QEvent *); 33 | bool eventFilter(QObject *, QEvent *); 34 | 35 | private: 36 | void InitUI(); 37 | 38 | Ui::MainWindow *ui; 39 | 40 | QString m_currentPath; 41 | FileSystemModel* m_pFileSystemModel; 42 | 43 | QCompleter* m_pCompleter; 44 | QDirModel* m_pCompleterModel; 45 | QString m_completerDir; 46 | }; 47 | 48 | #endif // MAINWINDOW_H 49 | -------------------------------------------------------------------------------- /src/MainApps/QtAddressBar/MainWindow.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | MainWindow 4 | 5 | 6 | 7 | 0 8 | 0 9 | 562 10 | 414 11 | 12 | 13 | 14 | MainWindow 15 | 16 | 17 | QMainWindow{ 18 | background-color: rgb(255, 255, 255); 19 | } 20 | 21 | QScrollBar:vertical { 22 | border:none; 23 | background: transparent; 24 | width: 10px; 25 | } 26 | 27 | QScrollBar::handle:vertical { 28 | border-radius:3px; 29 | background: #DDDDDD; 30 | min-height: 60px; 31 | } 32 | QScrollBar::add-line:vertical { 33 | border: none; 34 | height: 0px; 35 | } 36 | 37 | QScrollBar::sub-line:vertical { 38 | border: none; 39 | height: 0px; 40 | } 41 | 42 | QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { 43 | background: transparent; 44 | } 45 | 46 | 47 | 48 | QScrollBar:horizontal { 49 | border:none; 50 | background: transparent; 51 | height:10px; 52 | 53 | } 54 | QScrollBar::handle:horizontal { 55 | border-radius:3px; 56 | background: #DDDDDD; 57 | min-width: 60px; 58 | } 59 | QScrollBar::add-line:horizontal { 60 | border: none; 61 | width: 0px; 62 | } 63 | 64 | QScrollBar::sub-line:horizontal { 65 | border: none; 66 | width: 0px; 67 | } 68 | 69 | QScrollBar::add-page:horizontal, QScrollBar::sub-page:horizontal { 70 | background: transparent; 71 | } 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 0 80 | 23 81 | 82 | 83 | 84 | 85 | Microsoft YaHei UI 86 | 8 87 | 88 | 89 | 90 | QLineEdit{ 91 | border: 1px solid rgb(217, 217, 217); 92 | color:#333333; 93 | } 94 | 95 | QLineEdit:focus{ 96 | border: 1px solid rgb(0, 120, 215); 97 | } 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | reset 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | QtAddressBar 123 | QLineEdit 124 |
QtAddressBar.h
125 |
126 |
127 | 128 | 129 |
130 | -------------------------------------------------------------------------------- /src/MainApps/QtAddressBar/MenuWidget.cpp: -------------------------------------------------------------------------------- 1 | #include "MenuWidget.h" 2 | #include "ui_MenuWidget.h" 3 | 4 | #include 5 | #include 6 | 7 | MenuWidget::MenuWidget(bool isRoot, QWidget *parent) : 8 | QWidget(parent), 9 | ui(new Ui::MenuWidget), 10 | m_bRoot(isRoot) 11 | { 12 | ui->setupUi(this); 13 | 14 | if(m_bRoot) { 15 | m_pRootModel = new QStandardItemModel(this); 16 | ui->listView->setModel(m_pRootModel); 17 | setRootModel(); 18 | } 19 | else { 20 | m_pDirModel = new QDirModel(this); 21 | m_pDirModel->setReadOnly(false); 22 | m_pDirModel->setFilter(QDir::Dirs | QDir::NoDotAndDotDot); 23 | ui->listView->setModel(m_pDirModel); 24 | } 25 | 26 | // ui->listView->setItemDelegate(m_Delegate); 27 | ui->listView->setSpacing(0); 28 | ui->listView->setViewMode(QListView::ListMode); 29 | ui->listView->setResizeMode(QListView::Adjust); 30 | ui->listView->setDragEnabled(false); 31 | } 32 | 33 | MenuWidget::~MenuWidget() 34 | { 35 | delete ui; 36 | } 37 | 38 | void MenuWidget::updateDirModel(const QString &path) 39 | { 40 | QFileInfo info(path); 41 | if(info.isDir()) { 42 | m_pDirModel->refresh(m_pDirModel->index(path)); 43 | ui->listView->setRootIndex(m_pDirModel->index(path)); 44 | } 45 | } 46 | 47 | void MenuWidget::adjustMenuSize() 48 | { 49 | 50 | } 51 | 52 | void MenuWidget::setRootModel() 53 | { 54 | m_pRootModel->clear(); 55 | 56 | QStandardItem* item1 = new QStandardItem(); 57 | item1->setData(QIcon(":/res/dir.png"), Qt::DecorationRole); 58 | item1->setData(tr("Desktop"), Qt::DisplayRole); 59 | item1->setData(QStandardPaths::writableLocation(QStandardPaths::DesktopLocation), Qt::UserRole + 1); 60 | m_pRootModel->appendRow(item1); 61 | 62 | QStandardItem* item2 = new QStandardItem(); 63 | item2->setData(QIcon(":/res/dir.png"), Qt::DecorationRole); 64 | item2->setData(tr("Documents"), Qt::DisplayRole); 65 | item2->setData(QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation), Qt::UserRole + 1); 66 | m_pRootModel->appendRow(item2); 67 | 68 | QStandardItem* item3 = new QStandardItem(); 69 | item3->setData(QIcon(":/res/dir.png"), Qt::DecorationRole); 70 | item3->setData(tr("Pictures"), Qt::DisplayRole); 71 | item3->setData(QStandardPaths::writableLocation(QStandardPaths::PicturesLocation), Qt::UserRole + 1); 72 | m_pRootModel->appendRow(item3); 73 | } 74 | 75 | void MenuWidget::on_listView_clicked(const QModelIndex &index) 76 | { 77 | QString path = index.data(Qt::UserRole + 1).toString(); 78 | qDebug() << "path: " << path; 79 | 80 | emit SClickPath(path); 81 | 82 | } 83 | -------------------------------------------------------------------------------- /src/MainApps/QtAddressBar/MenuWidget.h: -------------------------------------------------------------------------------- 1 | #ifndef MENUWIDGET_H 2 | #define MENUWIDGET_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | namespace Ui { 9 | class MenuWidget; 10 | } 11 | 12 | class MenuWidget : public QWidget 13 | { 14 | Q_OBJECT 15 | 16 | public: 17 | explicit MenuWidget(bool isRoot, QWidget *parent = 0); 18 | ~MenuWidget(); 19 | 20 | void updateDirModel(const QString &str); 21 | 22 | signals: 23 | void SClickPath(const QString &path); 24 | 25 | private slots: 26 | void on_listView_clicked(const QModelIndex &index); 27 | 28 | private: 29 | void adjustMenuSize(); 30 | void setRootModel(); 31 | 32 | private: 33 | Ui::MenuWidget *ui; 34 | 35 | bool m_bRoot; 36 | QDirModel* m_pDirModel; 37 | QStandardItemModel* m_pRootModel; 38 | }; 39 | 40 | #endif // MENUWIDGET_H 41 | -------------------------------------------------------------------------------- /src/MainApps/QtAddressBar/MenuWidget.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | MenuWidget 4 | 5 | 6 | 7 | 0 8 | 0 9 | 217 10 | 289 11 | 12 | 13 | 14 | Form 15 | 16 | 17 | 18 | 0 19 | 20 | 21 | 0 22 | 23 | 24 | 0 25 | 26 | 27 | 0 28 | 29 | 30 | 0 31 | 32 | 33 | 34 | 35 | border:none; 36 | background:transparent; 37 | 38 | 39 | Qt::ScrollBarAlwaysOff 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /src/MainApps/QtAddressBar/NoFocusRectStyle.h: -------------------------------------------------------------------------------- 1 | #ifndef NOFOCUSRECTSTYLE_H 2 | #define NOFOCUSRECTSTYLE_H 3 | #include 4 | 5 | class NoFocusRectStyle : public QProxyStyle { 6 | public: 7 | NoFocusRectStyle(QStyle *baseStyle) : QProxyStyle(baseStyle) {} 8 | void drawPrimitive(PrimitiveElement element, 9 | const QStyleOption *option, 10 | QPainter *painter, 11 | const QWidget *widget = 0) const { 12 | if (element == QStyle::PE_FrameFocusRect) { 13 | return; 14 | } 15 | QProxyStyle::drawPrimitive(element, option, painter, widget); 16 | } 17 | }; 18 | 19 | #endif // NOFOCUSRECTSTYLE_H 20 | -------------------------------------------------------------------------------- /src/MainApps/QtAddressBar/QtAddressBar.cpp: -------------------------------------------------------------------------------- 1 | #include "QtAddressBar.h" 2 | #include "AddressItem.h" 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #define ROOT_ICON_WIDTH 34 14 | 15 | QtAddressBar::QtAddressBar(QWidget *parent) : 16 | QLineEdit(parent), 17 | m_pressed(false), 18 | m_bSelectText(false) 19 | { 20 | m_pMainLayout = new QHBoxLayout(); 21 | m_pMainLayout->setContentsMargins(1, 1, 1, 1); 22 | m_pMainLayout->setSpacing(0); 23 | setLayout(m_pMainLayout); 24 | 25 | m_addressGroup = new QButtonGroup(this); 26 | m_addressGroup->setExclusive(true); 27 | m_lastCheckBtn = nullptr; 28 | 29 | connect(m_addressGroup, SIGNAL(buttonClicked(QAbstractButton*)), this, SLOT(onGroupBtnClicked(QAbstractButton*))); 30 | 31 | this->clearFocus(); 32 | setMouseTracking(true); 33 | } 34 | 35 | QtAddressBar::~QtAddressBar() 36 | { 37 | 38 | } 39 | 40 | void QtAddressBar::UpdateCurrentPath(const QString &path) 41 | { 42 | this->clearFocus(); 43 | clearAddressItem(); 44 | 45 | m_currentPath = QString(path).replace("\\", "/"); 46 | setText(QString()); 47 | 48 | int itemsWidth = 0; 49 | int contentWidth = width(); 50 | 51 | QStringList itemList = m_currentPath.split("/", QString::SkipEmptyParts); 52 | 53 | //add root icon 54 | QLabel *rootIcon = new QLabel(this); 55 | rootIcon->setFixedSize(17, 20); 56 | rootIcon->setStyleSheet(QString("QLabel{background-image: url(:/res/dir.png);}")); 57 | 58 | m_pMainLayout->addWidget(rootIcon); 59 | 60 | //add path draw control 61 | AddressItem* root = new AddressItem(QString(), QString(), true, this); 62 | m_pMainLayout->addWidget(root); 63 | m_addressGroup->addButton(root, 0); 64 | 65 | contentWidth = contentWidth - ROOT_ICON_WIDTH; 66 | 67 | for(int i=itemList.count()-1; i >= 0; i--) 68 | { 69 | QString fullPath; 70 | 71 | // if(itemList[i].isEmpty()) {} 72 | 73 | for(int j=0; j <= i; ++j) 74 | { 75 | fullPath +=itemList[j]+"/"; 76 | } 77 | AddressItem* item = new AddressItem(itemList[i], fullPath, false, this); 78 | itemsWidth += item->width(); 79 | // qDebug() << "itemsWidth" << itemsWidth; 80 | 81 | m_pMainLayout->insertWidget(2, item); 82 | connect(item, &AddressItem::SClickPath, this, &QtAddressBar::SCurrentPathChanged); 83 | 84 | if(itemsWidth < contentWidth) { 85 | item->show(); 86 | m_addressGroup->addButton(item, i); 87 | } 88 | else { 89 | item->hide(); 90 | } 91 | } 92 | 93 | if(itemsWidth > contentWidth) { 94 | root->setBackIcon(true); 95 | } 96 | 97 | m_pMainLayout->addStretch(); 98 | } 99 | 100 | void QtAddressBar::closeMenu() 101 | { 102 | if(nullptr != m_lastCheckBtn) { 103 | m_addressGroup->setExclusive(false); 104 | m_lastCheckBtn->setChecked(false); 105 | m_addressGroup->setExclusive(true); 106 | 107 | m_lastCheckBtn = nullptr; 108 | } 109 | } 110 | 111 | void QtAddressBar::mousePressEvent(QMouseEvent *event) 112 | { 113 | if(event->button()==Qt::LeftButton) 114 | { 115 | m_pressed = true; 116 | // if(m_areaPath.contains(e->pos())) { 117 | } 118 | 119 | QLineEdit::mousePressEvent(event); 120 | } 121 | 122 | void QtAddressBar::mouseReleaseEvent(QMouseEvent *event) 123 | { 124 | if(event->button()==Qt::LeftButton && m_pressed) 125 | { 126 | qDebug() << "click white space"; 127 | m_pressed = false; 128 | clearAddressItem(); 129 | 130 | setText(m_currentPath); 131 | 132 | if(m_bSelectText) { 133 | deselect(); 134 | m_bSelectText = false; 135 | } 136 | else { 137 | selectAll(); 138 | m_bSelectText = true; 139 | } 140 | } 141 | 142 | QLineEdit::mouseReleaseEvent(event); 143 | } 144 | 145 | void QtAddressBar::mouseMoveEvent(QMouseEvent *event) 146 | { 147 | if(0 != m_addressGroup->checkedButton()) { 148 | foreach (QAbstractButton *button, m_addressGroup->buttons()) { 149 | if(button->geometry().contains(event->pos()) && m_addressGroup->checkedButton() != button) { 150 | AddressItem * btn = qobject_cast(button); 151 | btn->setChecked(true); 152 | m_lastCheckBtn = btn; 153 | // btn->showMenu(); 154 | } 155 | } 156 | } 157 | 158 | QLineEdit::mouseMoveEvent(event); 159 | } 160 | 161 | void QtAddressBar::focusInEvent(QFocusEvent *event) 162 | { 163 | QLineEdit::focusInEvent(event); 164 | } 165 | 166 | void QtAddressBar::focusOutEvent(QFocusEvent *event) 167 | { 168 | QFileInfo info(this->text()); 169 | if(info.isDir()) { 170 | m_currentPath = info.absoluteFilePath(); 171 | } 172 | 173 | UpdateCurrentPath(m_currentPath); 174 | 175 | QLineEdit::focusOutEvent(event); 176 | } 177 | 178 | void QtAddressBar::resizeEvent(QResizeEvent *event) 179 | { 180 | if(m_pMainLayout->count() >= 2) { 181 | int contentWidth = event->size().width() - ROOT_ICON_WIDTH; 182 | int itemsWidth = 0; 183 | 184 | foreach (QAbstractButton *button, m_addressGroup->buttons()) { 185 | m_addressGroup->removeButton(button); 186 | } 187 | m_lastCheckBtn = nullptr; 188 | 189 | for (int i=m_pMainLayout->count()-2; i >= 2; i--) //root item(0,1) always show, count()-1 is space item 190 | { 191 | QLayoutItem *item = m_pMainLayout->itemAt(i); 192 | AddressItem *addressItem = qobject_cast(item->widget()); 193 | if (addressItem != 0) 194 | { 195 | addressItem->hide(); 196 | itemsWidth += addressItem->width(); 197 | 198 | if(itemsWidth < contentWidth) { 199 | addressItem->show(); 200 | m_addressGroup->addButton(addressItem, i); 201 | } 202 | } 203 | } 204 | 205 | QLayoutItem *root = m_pMainLayout->itemAt(1); 206 | AddressItem *rootItem = qobject_cast(root->widget()); 207 | if(itemsWidth > contentWidth) { 208 | rootItem->setBackIcon(true); 209 | } 210 | else { 211 | rootItem->setBackIcon(false); 212 | } 213 | } 214 | 215 | clearFocus(); 216 | 217 | QLineEdit::resizeEvent(event); 218 | } 219 | 220 | void QtAddressBar::keyPressEvent(QKeyEvent *event) 221 | { 222 | if (event->key() == Qt::Key_Return) { 223 | QString pathStr = this->text(); 224 | pathStr.replace("\\", "/"); 225 | QFileInfo info(pathStr); 226 | 227 | if(info.isDir()) { 228 | m_currentPath = info.absoluteFilePath(); 229 | } 230 | else { 231 | qDebug() << "not dir"; 232 | } 233 | 234 | UpdateCurrentPath(m_currentPath); 235 | } 236 | 237 | QLineEdit::keyPressEvent(event); 238 | } 239 | 240 | void QtAddressBar::onGroupBtnClicked(QAbstractButton *button) 241 | { 242 | if(button == m_lastCheckBtn) { 243 | m_addressGroup->setExclusive(false); 244 | button->setChecked(false); 245 | m_addressGroup->setExclusive(true); 246 | 247 | m_lastCheckBtn = nullptr; 248 | } 249 | else { 250 | m_lastCheckBtn = button; 251 | } 252 | 253 | } 254 | 255 | void QtAddressBar::clearAddressItem() 256 | { 257 | foreach (QAbstractButton *button, m_addressGroup->buttons()) { 258 | m_addressGroup->removeButton(button); 259 | } 260 | m_lastCheckBtn = nullptr; 261 | 262 | QLayoutItem *child; 263 | while ((child = m_pMainLayout->takeAt(0)) != 0) { 264 | if(child->widget()) 265 | { 266 | // delete child->widget(); 267 | child->widget()->deleteLater(); 268 | } 269 | delete child; 270 | } 271 | } 272 | 273 | -------------------------------------------------------------------------------- /src/MainApps/QtAddressBar/QtAddressBar.h: -------------------------------------------------------------------------------- 1 | #ifndef QTADDRESSBAR_H 2 | #define QTADDRESSBAR_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "AddressItem.h" 10 | 11 | class QtAddressBar : public QLineEdit 12 | { 13 | Q_OBJECT 14 | 15 | public: 16 | explicit QtAddressBar(QWidget *parent = 0); 17 | ~QtAddressBar(); 18 | 19 | void UpdateCurrentPath(const QString &path); 20 | void closeMenu(); 21 | 22 | signals: 23 | void SCurrentPathChanged(const QString &path); 24 | 25 | protected: 26 | void mousePressEvent(QMouseEvent*); 27 | void mouseReleaseEvent(QMouseEvent*); 28 | void mouseMoveEvent(QMouseEvent*); 29 | void focusInEvent(QFocusEvent *); 30 | void focusOutEvent(QFocusEvent *); 31 | void resizeEvent(QResizeEvent*); 32 | void keyPressEvent(QKeyEvent *); 33 | 34 | private slots: 35 | void onGroupBtnClicked(QAbstractButton*); 36 | 37 | private: 38 | void clearAddressItem(); 39 | 40 | private: 41 | bool m_pressed; 42 | bool m_bSelectText; 43 | QString m_currentPath; 44 | QButtonGroup* m_addressGroup; 45 | QAbstractButton* m_lastCheckBtn; 46 | QHBoxLayout* m_pMainLayout; 47 | }; 48 | 49 | #endif // QTADDRESSBAR_H 50 | -------------------------------------------------------------------------------- /src/MainApps/QtAddressBar/QtAddressBar.pro: -------------------------------------------------------------------------------- 1 | #------------------------------------------------- 2 | # 3 | # Project created by QtCreator 2018-05-28T14:34:58 4 | # 5 | #------------------------------------------------- 6 | 7 | QT += core gui 8 | 9 | greaterThan(QT_MAJOR_VERSION, 4): QT += widgets 10 | 11 | TARGET = QtAddressBar 12 | TEMPLATE = app 13 | 14 | include(./../../Path.pri) 15 | 16 | SOURCES += main.cpp\ 17 | MainWindow.cpp \ 18 | FileSystemModel.cpp \ 19 | QtAddressBar.cpp \ 20 | AddressItem.cpp \ 21 | MenuWidget.cpp 22 | 23 | HEADERS += MainWindow.h \ 24 | NoFocusRectStyle.h \ 25 | FileSystemModel.h \ 26 | QtAddressBar.h \ 27 | AddressItem.h \ 28 | MenuWidget.h 29 | 30 | FORMS += MainWindow.ui \ 31 | MenuWidget.ui 32 | 33 | RESOURCES += \ 34 | res.qrc 35 | -------------------------------------------------------------------------------- /src/MainApps/QtAddressBar/main.cpp: -------------------------------------------------------------------------------- 1 | #include "MainWindow.h" 2 | #include "NoFocusRectStyle.h" 3 | #include 4 | 5 | int main(int argc, char *argv[]) 6 | { 7 | QApplication app(argc, argv); 8 | NoFocusRectStyle *style = new NoFocusRectStyle(app.style()); 9 | app.setStyle(style); 10 | 11 | MainWindow w; 12 | w.show(); 13 | 14 | return app.exec(); 15 | } 16 | -------------------------------------------------------------------------------- /src/MainApps/QtAddressBar/res.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | res/arrow_down.png 4 | res/arrow_right.png 5 | res/dir.png 6 | res/arrow_back.png 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/MainApps/QtAddressBar/res/arrow_back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Longxr/QtAddressBar/7b2103658cc1744f5bc75a06fbd964366854b20a/src/MainApps/QtAddressBar/res/arrow_back.png -------------------------------------------------------------------------------- /src/MainApps/QtAddressBar/res/arrow_down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Longxr/QtAddressBar/7b2103658cc1744f5bc75a06fbd964366854b20a/src/MainApps/QtAddressBar/res/arrow_down.png -------------------------------------------------------------------------------- /src/MainApps/QtAddressBar/res/arrow_right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Longxr/QtAddressBar/7b2103658cc1744f5bc75a06fbd964366854b20a/src/MainApps/QtAddressBar/res/arrow_right.png -------------------------------------------------------------------------------- /src/MainApps/QtAddressBar/res/dir.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Longxr/QtAddressBar/7b2103658cc1744f5bc75a06fbd964366854b20a/src/MainApps/QtAddressBar/res/dir.png -------------------------------------------------------------------------------- /src/Path.pri: -------------------------------------------------------------------------------- 1 | unix { 2 | DEFINES += __UNIX__ 3 | 4 | exists("/Applications/Launchpad.app") { 5 | SystemType=Mac 6 | DEFINES += __PLATFORM_MAC__ \ 7 | __FREEBSD__ 8 | } else { 9 | UNAME=$$system(cat /etc/issue) 10 | contains(UNAME, Ubuntu) { 11 | SystemType=Ubuntu 12 | DEFINES += __PLATFORM_UBUNTU__ 13 | } 14 | 15 | contains(UNAME, Debian): { 16 | SystemType=Debian 17 | DEFINES += __PLATFORM_DEBIAN__ 18 | } 19 | } 20 | } 21 | 22 | win32 { 23 | SystemType=Windows 24 | DEFINES += __PLATFORM_WIN__ 25 | } 26 | 27 | 28 | CONFIG(release, debug|release) { 29 | BuildType=release 30 | DEFINES += __RELEASE 31 | CONFIG += warn_off 32 | } else { 33 | BuildType=debug 34 | DEFINES += __DEBUG 35 | } 36 | 37 | INTERMEDIATE_DIR = $$PWD/../Intermediate/$$BuildType 38 | 39 | DESTDIR = $$PWD/../RunImage/$$BuildType 40 | OUT_PWD = $$INTERMEDIATE_DIR/$$TARGET 41 | MOC_DIR = $$INTERMEDIATE_DIR/$$TARGET 42 | OBJECTS_DIR = $$INTERMEDIATE_DIR/$$TARGET 43 | RCC_DIR = $$INTERMEDIATE_DIR/$$TARGET 44 | -------------------------------------------------------------------------------- /src/QtAddressBar.pro: -------------------------------------------------------------------------------- 1 | TEMPLATE = subdirs 2 | 3 | #SUBDIRS += Libraries 4 | SUBDIRS += MainApps 5 | CONFIG += ordered 6 | --------------------------------------------------------------------------------