Как создать свой проводник для windows

Если вам не нравится стандартный проводник Windows, вы можете создать свой собственный, настроенный под свои нужды. Например, вы можете добавить функцию быстрого доступа к папкам, которые вы используете чаще всего, или настроить цвет и шрифт интерфейса. В этой статье мы расскажем, как создать свой проводник в Windows.

Шаг 1: Запустите редактор реестра.

Нажмите клавишу Win+R, чтобы открыть окно «Выполнить». Введите «regedit» и нажмите Enter. Это откроет редактор реестра Windows, где вы сможете изменять настройки, связанные с проводником.

Шаг 2: Создайте новый ключ.

Перейдите к следующей ветке реестра:

HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer

Щелкните правой кнопкой мыши на пустом месте в правой части окна и выберите «Новый» -> «Ключ». Назовите этот ключ «NoTrayContextMenu».

Шаг 3: Создайте новое значение.

Щелкните правой кнопкой мыши на новом ключе и выберите «Новый» -> «DWORD-значение (32 бита)». Назовите это значение «NoTrayContextMenu».

Шаг 4: Установите значение.

Дважды щелкните на значении «NoTrayContextMenu», чтобы открыть окно «Изменить значение DWORD». Установите значение «1» и нажмите «ОК». Таким образом, вы отключите контекстное меню Панели задач, которая может мешать в работе с проводником.

Шаг 5: Перезапустите проводник.

Нажмите клавишу Ctrl+Shift+Esc, чтобы открыть диспетчер задач. Найдите в списке процесс «Проводник» и нажмите на него правой кнопкой мыши. Выберите «Завершить задачу». После этого Проводник перезапустится автоматически, а вы сможете проверить настройки своего нового проводника.

Шаг 6: Настройте проводник под свои нужды.

Перейдите в любую папку, а затем щелкните правой кнопкой мыши на верхней панели проводника. Нажмите на «Настроить панель инструментов и адреса», чтобы настроить расположение элементов, добавить новые кнопки и изменить цвет интерфейса. Настраивайте проводник так, как вам удобно.

В заключение, создание своего проводника может помочь вам улучшить ваш опыт работы с Windows и сделать его более персональным. Важно помнить, что при работе в редакторе реестра, необходимо быть осторожным и не изменять значения, если вы не уверены в своих действиях.

16 / 16 / 0

Регистрация: 10.04.2011

Сообщений: 271

1

.NET 4.x

14.05.2012, 14:58. Показов 23945. Ответов 18


Студворк — интернет-сервис помощи студентам

Здравствуйте.
В учебном заведении на экзамен, срок которого — неделя, мне выпало «написать проводник».) В целом, должно выйти «нечто, похожее на проводник винды», конечно не идеально точь в точь похоже, но хотя-бы основные функции должны присутствовать.

Вопрос заключается в том.. с чего вообще начать? Я честно говоря даже не знаю, с какой стороны подступиться к подобному заданию.
Хотелось бы набросать «план действий»..
Для начала, как я понимаю, нужно создать ListView, как-то ( основная сложность ) прикрутить к нему отображение файлов и папок в определенной директории, и что не менее сложно — научить его переходить из папки в папку. Потом можно как-то прикрутить отображение «даты изменения», «типа», «размера» и т.д., если это возможно..

В общем, буду очень благодарен за дельные советы)



0



Etrimus

398 / 365 / 54

Регистрация: 23.05.2010

Сообщений: 716

15.05.2012, 10:47

2

Для начала посмотри про классы и методы получения списков файлов и папок.
Класс File — http://msdn.microsoft.com/ru-r… .file.aspx
Класс FileInfo — http://msdn.microsoft.com/ru-r… einfo.aspx
Класс Directory — http://msdn.microsoft.com/ru-r… ctory.aspx
Класс DirectoryInfo — http://msdn.microsoft.com/ru-r… yinfo.aspx
С их помощью можно вывести в ЛистВью списки файлов и папок, а потом можно копировать, перемещать и т.д. На этом форуме есть тема про это — Пространство имен — System.IO (Работа с файлами, директориями, дисками, памятью)
Например, начни с того, что при запуске программы отображаются локальные диски. Тут помогает класс DriveInfo, у него есть метод GetDrives()

C#
1
DriveInfo[] allDrives = DriveInfo.GetDrives();

Дальше обрабатываешь события двойного клика на элементы в ЛистВью и отображаешь список файлав и папок в той папке, по которой кликнуто в ЛистВью.
Можно сделать контектстное меню у элементов ЛистВью, из которого можно, например, удалять, переименовывать файлы и папки.
В классах File и FileInfo есть возможности узнать атрибуты файлов, такие как размер, даты создания/изменения, и можно визуально скрывать в ЛистВью файлы с атрибутом Скрытый, ну и так далее, полёт фантазии.



1



16 / 16 / 0

Регистрация: 10.04.2011

Сообщений: 271

16.05.2012, 14:41

 [ТС]

3

Посмотрел на msdn-е и взял за основу это:
http://msdn.microsoft.com/ru-ru/library/ms171645
Создал текстбокс, в который пользователь забивает путь, кнопку «перейти» и «вверх», реализовал. Работает.)
Возникли следующие проблемы:

Проблема 1:
При попытке поиска по пути C:\ или D:\ выдает ошибку о правах доступа куда-то. В обычные папки заходит нормально.
Проблема 2:
Как удалить предыдущий узел? А то после каждой «перейти» создается в левом окошке новый узел, а старый не исчезает?
Проблема 3:
Как реализовать разные значки для разных расширений файлов?
И да — можно ли «вытащить» значки из проводника винды, или откуда-то из винды вообще, чтобы не нужно было их принтскринить?) А то принтскринить значки — изврат.



0



Etrimus

398 / 365 / 54

Регистрация: 23.05.2010

Сообщений: 716

16.05.2012, 19:22

4

Пишу с нетбука, где нет студии, не отвечу на вопросы про код.

Цитата
Сообщение от Arimand
Посмотреть сообщение

Как реализовать разные значки для разных расширений файлов?

Средствами C# можно так — http://msdn.microsoft.com/ru-r… .icon.aspx
Но это только для файлов. А вообще системные значки лежать в

Код

%SystemRoot%\system32\SHELL32.dll

Там куча системных картинок, вот только средствами одного NET достать их вроде как не выйдет, для этого придётся использовать WinAPI или сторонние классы. Поэтому для файлов можно брать иконки как я показал, я для папок задавать жестко, например, засунуть в ресурсы программы готовый файл.

И да — можно ли «вытащить» значки из проводника винды, или откуда-то из винды вообще

Что бы просто сохранить к себе на компьютер, есть специальные программы, например Resource Hacker или подобные.

Добавлено через 14 минут

Цитата
Сообщение от Arimand
Посмотреть сообщение

Как удалить предыдущий узел? А то после каждой «перейти» создается в левом окошке новый узел, а старый не исчезает?

У Treeview есть свойство Nodes, которое является массивом всех корневых элементов. Вот так можно удалить самый верхний элемент

C#
1
treeview1.Nodes[0].Remove()



1



16 / 16 / 0

Регистрация: 10.04.2011

Сообщений: 271

17.05.2012, 11:56

 [ТС]

5

Благодарю)
А что с дисками делать?
Ввожу в свою «адресную строку» диск C, выдает ошибку:

************** Текст исключения **************
System.UnauthorizedAccessException: Отказано в доступе по пути «C:\Documents and Settings\».

Ввожу диск D — начинает что-то ОЧЕНЬ долго грузить почему-то, а потом — снова же «отказано в доступе» к D:\System Volume Information\
Что нужно сделать, чтобы оно хотя-бы игнорировала те папки, к которым не может получить доступ?



0



398 / 365 / 54

Регистрация: 23.05.2010

Сообщений: 716

17.05.2012, 12:45

6

Цитата
Сообщение от Arimand
Посмотреть сообщение

Ввожу в свою «адресную строку» диск C

Цитата
Сообщение от Arimand
Посмотреть сообщение

Отказано в доступе по пути «C:\Documents and Settings\».

Прочитай обе строчки ещё раз. Из них видно, что ты чего-то не то вводишь, потому что по факту программа пытается зайти не на диск С, а на C:\Documents and Settings\. В коде значит где-то намудрил.
Это конкретно про код, а вообще про ошибку Отказано в доступе по пути. Она вылетает, если у пользователя нет прав для входа в указанную папку. Попробуй даже сам, не из своей программы зайти на компе в папку D:\System Volume Information\, получишь тоже самое.
В Documents and Settings у меня нормально заходит, может быть прав твоей учётной записи не достаточно доя этого.
То что пускает не во все папки, это нормально, в Семерке вообще много куда не пустит.



2



Arimand

16 / 16 / 0

Регистрация: 10.04.2011

Сообщений: 271

17.05.2012, 13:06

 [ТС]

7

Цитата
Сообщение от Etrimus
Посмотреть сообщение

Прочитай обе строчки ещё раз. Из них видно, что ты чего-то не то вводишь, потому что по факту программа пытается зайти не на диск С, а на C:\Documents and Settings\. В коде значит где-то намудрил.
Это конкретно про код, а вообще про ошибку Отказано в доступе по пути. Она вылетает, если у пользователя нет прав для входа в указанную папку. Попробуй даже сам, не из своей программы зайти на компе в папку D:\System Volume Information\, получишь тоже самое.
В Documents and Settings у меня нормально заходит, может быть прав твоей учётной записи не достаточно доя этого.
То что пускает не во все папки, это нормально, в Семерке вообще много куда не пустит.

Посмотрел еще раз на код, понял, в чем проблема: программа рекурсивно перебирает все папки внутри заданой, и таким образом формирует «дерево» папок.
Моя же задача ( насколько я понимаю ) заключается в том, чтобы переделать данный код на такой, который формировал бы только список папок в _данной_ дирректории.
Права учетной записи — администраторские. И да — семерка)

То, что оно «не пускает» — это понятно. Как сделать исключение, чтобы оно «обходило стороной» такие гадкие папки?
Прошу прощения за ламерский вопрос Проблему решил с помощью:

C#
1
try{ ...код... }



0



Etrimus

398 / 365 / 54

Регистрация: 23.05.2010

Сообщений: 716

17.05.2012, 13:14

8

Цитата
Сообщение от Arimand
Посмотреть сообщение

формировал бы только список папок в _данной_ дирректории.

Можно сразу получить массив с путями и к файлам, и к папкам. Удобно.

C#
1
string[] array = Directory.GetFileSystemEntries(@"C:\");

Добавлено через 3 минуты

Цитата
Сообщение от Arimand
Посмотреть сообщение

Как сделать исключение, чтобы оно «обходило стороной» такие гадкие папки?

Обрабатывай исключения в программе. Вот простой пример, почитай про исключения в C#.

C#
1
2
3
4
5
6
7
8
9
            try
            {
                //DirectoryInfo dir = new DirectoryInfo(@"C:\System Volume Information\");
                string[] arr = Directory.GetFileSystemEntries(@"C:\System Volume Information\");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
            }



1



16 / 16 / 0

Регистрация: 10.04.2011

Сообщений: 271

17.05.2012, 13:23

 [ТС]

9

Спасибо, проблему с обработкой я решил.)
Теперь вопрос уже другой:
Как лучше реализовать вырезание/копирование/вставку файлов?
В принципе, по логике вещей — к узлам ( файлам и папкам ) привязывается контекстное меню, к нему уже привязываются функции: с помощью класса FileInfo:
-самое простое — удаление: Delete()
-MoveTo() — использовать для вырезания/вставки, а заодно можно и для переименования
А вот как лучше реализовать копирование?

+К этому: как заставить программу открыть файл ( так, как они открываются через проводник — в смысле .txt через блокнот, приложение — как приложение, .doc — через офис и т.д. ) ?



0



Etrimus

398 / 365 / 54

Регистрация: 23.05.2010

Сообщений: 716

17.05.2012, 13:34

10

Цитата
Сообщение от Arimand
Посмотреть сообщение

А вот как лучше реализовать копирование?

Для файлов просто

C#
1
File.Copy

Для папок. Ну тут придётся руками… Создаём в нужном месте папку, и в неё циклом копируем (File.Copy) все файлы из копируемой папки.
Либо можно халяву замутить…
Добавяем в проект ссылку на пространство имен Microsoft.VisualBasic. И пишем.

C#
1
Microsoft.VisualBasic.FileIO.FileSystem.

И после символа точки ВизуалСтудия вывалит всё, что нужно. Копировать, перемещать, удалять, переименовывать файлы и папки. Халява полная, но это если прокатит у тебя перед преподом.



1



16 / 16 / 0

Регистрация: 10.04.2011

Сообщений: 271

17.05.2012, 13:45

 [ТС]

11

Замечательно, буду кодить) Еще раз благодарю)
Халявой пожалуй воспользуюсь. Политика учебного заведения — стимулирование людей к «самостоятельному получению знаний», так что будет только в плюс.



0



Etrimus

398 / 365 / 54

Регистрация: 23.05.2010

Сообщений: 716

17.05.2012, 13:49

12

Ну тогда всё ОК, вот ещё про запуск файлов.

C#
1
System.Diagnostics.Process.Start(@"C:\Вася\Файл.xlsx");

К стати, если написать туда не путь к файлу, а интернет-адрес, то запустится браузер и перейдёт на этот адрес.



0



16 / 16 / 0

Регистрация: 10.04.2011

Сообщений: 271

17.05.2012, 14:21

 [ТС]

13

Снова появилась неожиданная проблема:
Как подключить ContextMenuStrip к элементу listView? К TreeView подключается нормально.



0



Etrimus

398 / 365 / 54

Регистрация: 23.05.2010

Сообщений: 716

17.05.2012, 15:31

14

А в чём проблема, подключаешь через Студию контекстное меню. У каждого элемента контекстного меню есть событие Click. Подписываешься на него, а в событии уже работаешь с выделенными в ЛистВью элементами.

C#
1
2
3
4
        private void копироватьToolStripMenuItem_Click(object sender, EventArgs e)
        {
            MessageBox.Show(listView1.SelectedItems[0].Text);
        }

Показал в окошке текс первого выделенного элемента в ЛистВью.



0



16 / 16 / 0

Регистрация: 10.04.2011

Сообщений: 271

17.05.2012, 15:57

 [ТС]

15

Нет, я не о том.
Мне нужно, чтобы при нажатии правой кнопкой на элемент listView вылазило контекстное меню ( как в проводнике ), а не обрабатывать выделенный элемент через ToolStripMenu.



0



Местный Ёжидзе

42 / 44 / 4

Регистрация: 03.03.2010

Сообщений: 225

17.05.2012, 19:14

16

Arimand,
Используй ContextMenuStrip. Что бы привязать его к элементу управления. В элементе управления укажи имя контекстного меню. И всё будет работать.

В визуальном редакторе в свойствах listView увидишь ContextMenuStrip. Вот и всё.
Далее настраиваешь контекстное меню под себя.



0



16 / 16 / 0

Регистрация: 10.04.2011

Сообщений: 271

19.05.2012, 01:01

 [ТС]

17

Я не вижу возможности привязать ContextMenuStrip к итему listView. К самому listView оно привязывается легко. А к итему как привязать?

Добавлено через 22 минуты

Не по теме:

Предчувствую, мне предстоит бессонная ночка.



0



hitmen047

Местный Ёжидзе

42 / 44 / 4

Регистрация: 03.03.2010

Сообщений: 225

19.05.2012, 18:07

18

Arimand, что бы обратиться к выделенному итему в listView используй:

C#
1
string s = ListView.Items[track_list.SelectedIndices[0]].Text // пример получение текста выбранного элемента в ListView



0



IBe3yH4uk

0 / 0 / 0

Регистрация: 04.10.2012

Сообщений: 4

05.10.2012, 00:12

19

Доброго времени суток! тоже пишу файловый менеджер, хотелось бы спросить как реализовывали поднятие на уровень вверх. Вот моя реализация:

Реализация обработчика:

C#
1
2
3
4
5
6
7
8
private void button1_Click(object sender, EventArgs e)
        {
            OneLevelUp();
            listView1.Items.Clear();
            DisplayFolder();
            DisplayFiles();
            
        }

Реализация метода реализующего поднятие на один уровень вверх:

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
private void OneLevelUp()
        {
                int position = 0;
 
            // Find position of last "\" - (разделитель в пути к файлу)
                for (int counter = Fullpath.Length - 1; counter != 0; counter--)
                {
                    if (Fullpath[counter].ToString(CultureInfo.InvariantCulture) =="\\")
                    {
 
                        position = counter;
                        break;
                    }
                }
 
                // Get substring
            
                string result = Fullpath.Substring(0, position);
                //Console.WriteLine(result);
 
                if (result[result.Length - 1] == ':')
                {
                    
                    result += "\\";
                    LogicalDriver = result;
                    Fullpath = LogicalDriver;
                    Console.WriteLine("IF");
                    
                }
                else
                {
                    LogicalDriver = result;
                    Fullpath = LogicalDriver;
                    Console.WriteLine("ELSE");
                }
        }

Но вся проблема в том что когда я нажимаю на кнопку он почему то два раза заходит в метод, а по идеи должен всего 1 раз зайти. Помогите пожалуйста разобраться.



0



Простые шаги для создания собственного проводника на ПК

Проводник на ПК — это программа, которая позволяет управлять файлами и папками на компьютере. Она является одним из самых важных компонентов операционной системы Windows. Однако, если вам не нравится стандартный проводник на ПК, есть возможность создать свой собственный проводник с помощью простых шагов.

Шаг 1: Выбор платформы

Первым шагом для создания собственного проводника на ПК является выбор платформы. Существует множество бесплатных инструментов, которые могут быть использованы для создания проводника на ПК. Некоторые из них предназначены для определенных языков программирования, например, C# или Java. Выберите инструмент, который лучше всего подходит для ваших потребностей.

Шаг 2: Создание пользовательского интерфейса

Следующим шагом является создание пользовательского интерфейса. Это включает в себя разработку дизайна и функциональности вашего проводника на ПК. Здесь вы можете определить, какие элементы будут отображаться на вашей главной странице, сколько колонок и строк загрузится, каким образом будут отображаться файлы и многое другое.

Шаг 3: Создание программной логики

После создания пользовательского интерфейса необходимо добавить программную логику. Эта логика определяет, как ваш проводник на ПК будет реагировать на пользовательские действия, такие как открытие папки или перемещение файла в другую папку. Определите все возможные функции и действия, которые могут быть выполнены в вашем проводнике на ПК и добавьте их в код.

Шаг 4: Тестирование и отладка

Когда вы закончили создание пользовательского интерфейса и программной логики вашего проводника на ПК, следующим шагом должно стать тестирование и отладка вашего приложения. Тестирование может включать проверку на всех основных операционных системах, поиск ошибок и потенциальных проблем, исправление ошибок и улучшение производительности вашего проводника на ПК.

Шаг 5: Размещение созданного приложения в Интернете

Последний шаг в создании собственного проводника на ПК — это размещение вашего приложения в Интернете, чтобы сторонние пользователи могли использовать его. Вы можете разместить ваше приложение на специализированных сайтах для загрузки дополнительного ПО из Интернета.

Вывод

В заключение, создание собственного проводника на ПК может быть очень простым, если будете придерживаться вышеуказанных шагов. Соответствующий выбор платформы, создание пользовательского интерфейса, добавление программной логики, тестирование и отладка, а также размещение созданного приложения в Интернете поможет создать эффективный и удобный ПО для управления файлами и папками на вашем ПК.

Сегодня мы расширим использование модели в QListView.  Мы напишем свою версию Проводника Windows. Конечно, она не будет обладать всем функционалом, но, для демонстрации возможностей виджета, этого будет достаточно.

Источником данных для модели может быть любой источник данных, на этот раз этим источником будет файловая система ПК.

Создание модели

Создадим новый проект Qt Widgets и назовем его QListViewExplorer.

Добавим на форму QListView

Добавим класс для нашей модели – QListViewExplorerModel

Заголовок:

#ifndef QLISTVIEWEXPLORERMODEL_H
#define QLISTVIEWEXPLORERMODEL_H

#include <QDir>
#include <QModelIndex>

class QListViewExplorerModel: public QAbstractListModel
{
public:
    QListViewExplorerModel(QObject *parent=nullptr);
    int rowCount(const QModelIndex &) const;
    QVariant data(const QModelIndex &index, int role) const;

    void getFolderList(QString folderPath, QFileInfoList *dirList);

private:
    QFileInfoList *aDirList;

};

#endif // QLISTVIEWEXPLORERMODEL_H

Реализация:

#include "qlistviewexplorermodel.h"

QListViewExplorerModel::QListViewExplorerModel(QObject *parent)
    :QAbstractListModel(parent)
{

}

void QListViewExplorerModel::getFolderList(QString folderPath, QFileInfoList *dirList)
{
    QDir dir = QDir(folderPath);

    *dirList = dir.entryInfoList();

    this->aDirList = dirList;
}

int QListViewExplorerModel::rowCount(const QModelIndex &) const
{
    return this->aDirList->count();
}

QVariant QListViewExplorerModel::data( const QModelIndex &index, int role ) const
{

    QVariant value;

        switch ( role )
        {
            case Qt::DisplayRole: //string
            {
                value = this->aDirList->at(index.row()).fileName();
            }
            break;

            case Qt::UserRole: //data
            {
                value = this->aDirList->at(index.row()).fileName();
            }
            break;

            default:
                break;
        }

    return value;
}

Добавим код в конструктор формы MainWindow::MainWindow(QWidget *parent)

    this->aDirList = new QFileInfoList(); 

    this->model = new QListViewExplorerModel(); 

    this->model->getFolderList(".",this->aDirList); 

    this->ui->listView->setModel(model);

Добавим поля в заголовок:

private:
    Ui::MainWindow *ui;

    QFileInfoList *aDirList;

    QListViewExplorerModel *model;

Запустим

2020-12-17_16-26-45.png

Мы и получили список файлов папки, из которой производится запуск нашей программы.

Рассмотрим код модели:

В методе getFolderList() мы создаем экземпляр класса QDir. Данный класс позволяет получать доступ к файлам и папкам файловой системы, а также виртуально перемещаться по ним.

После этого мы получаем список файлов и папок, указанной папки и через указатель присваиваем значение этого списка полю класса, объявленному в нашей главной форме.

Как мы уже говорили в предыдущих статьях – модель не должна хранить данные, мы просто передаем ей указатель на переменную, в которой должна храниться информация. После этого мы обновляем указатель на эти данные, объявленный как поле самого класса.

Метод data() в нашем случае для всех ролей возвращает имя файла или папки, которые мы выбрали. В данный момент это несущественно.

Сортируем список папок и файлов

У нас есть список файлов и папок, но проблема в том, что содержимое списка отсортировано непонятно как — неясно где папка, а где файл.

Применим сортировку к списку. В методе модели getFolderList() изменим строку

    *dirList = dir.entryInfoList( QDir::NoFilter, QDir::DirsFirst);

QDir::NoFilter – указывает, что нам не нужна фильтрация (подробнее в документации Qt5 — https://doc.qt.io/qt-5/qdir.html#Filter-enum)

QDir::DirsFirst – задаёт метод сортировки – папки первыми, потом файлы (подробнее в документации Qt5 — https://doc.qt.io/qt-5/qdir.html#SortFlag-enum).

Запустим

2020-12-17_17-03-15.png

Уже лучше, но всё равно непонятно, где папка, а где файл. Давайте добавим иконки для каждой строки.

Для начала нам понадобятся сами иконки, скачать вы их можете с Яндекс.Диска — https://yadi.sk/d/_N4v7pySleb07A или с Github.

Создадим в корне проекта папку img и скопируем в нее файлы с иконками.

Создадим файл ресурса resource.qrc со следующим содержимым:

<RCC>
    <qresource prefix="/">
        <file>img/file.png</file>
        <file>img/folder.png</file>
        <file>img/zip.png</file>
        <file>img/folderup.png</file>
        <file>img/iconlist.png</file>
        <file>img/list.png</file>
    </qresource>
</RCC>

Добавим его к проекту.

Изменим метод модели data():

QVariant QListViewExplorerModel::data( const QModelIndex &index, int role ) const
{
    QVariant value;

        switch ( role )
        {
            case Qt::DisplayRole: //string
            {
                value = this->aDirList->at(index.row()).fileName();
            }
            break;

            case Qt::DecorationRole: //icon
            {
                if (this->aDirList->at(index.row()).isDir()) {
                    QPixmap icon = QPixmap(":/img/folder.png");
                    QPixmap tmp = icon.scaled(30, 30, Qt::KeepAspectRatio);
                    value = tmp;
                    break;
                }

                if (this->aDirList->at(index.row()).isFile()) {
                    QPixmap icon = QPixmap(":/img/file.png");
                    QPixmap tmp = icon.scaled(30, 30, Qt::KeepAspectRatio);
                    value = tmp;
                    break;
                }

                value = this->aDirList->at(index.row()).fileName();
            }
            break;

            case Qt::UserRole: //data
            {
                value = this->aDirList->at(index.row()).fileName();
            }
            break;

            default:
                break;
        }

    return value;
}

Запустим:

2020-12-17_17-52-25.png 

Здесь все просто, для роли Qt::DecorationRole мы возвращаем экземпляр класса QPixmap, в зависимости от типа элемента мы используем разные иконки и каждую, дополнительно, масштабируем.

Обратите внимание, мы используем временную переменную, для того, чтобы создать саму ионку. Если вы попробуете написать вот так:

value = QPixmap(":/img/file.png").scaled(30, 30, Qt::KeepAspectRatio);

То всё будет работать, но вы можете получить множество ошибок:

QPixmap::scaled: Pixmap is a null pixmap

У меня на одном ПК они появлялись, а на другом нет, неясно с чем это связано, поэтому я и использую временную переменную.

Фильтруем элементы списка

Осталось убрать папку с именем «.»

Для этого мы можем использовать фильтры метода entryInfoList()

    *dirList = dir.entryInfoList(QDir::NoDot | QDir::Files | QDir::Dirs, QDir::DirsFirst);

В данном случае мы использовали фильтр:

QDir::NoDot | QDir::Files | QDir::Dirs

Что означает: не показывать пункт с одной точкой, показывать файлы и папки.

Вы можете избавиться и от пункта с двумя точками, для этого достаточно добавить к фильтру еще одно значение:

QDir::NoDot | QDir::Files | QDir::Dirs | QDir::NoDotDot

Или переписать так:

QDir::NoDotAndDotDot | QDir::Files | QDir::Dirs

Что даст тот же результат.

Добавляем иконку для zip архивов

Давайте добавим еще кое-что, у всех файлов независимо от расширения, одна и та же иконка, давайте сделаем для отдельную zip-файлов.

Для таких файлов у нас уже есть иконка, осталось добавить код. Модернизируем метод data() нашей модели:

QVariant QListViewExplorerModel::data( const QModelIndex &index, int role ) const
{

    QVariant value;

        switch ( role )
        {
            case Qt::DisplayRole: //string
            {
                value = this->aDirList->at(index.row()).fileName();
            }
            break;

            case Qt::DecorationRole: //icon
            {
                if (this->aDirList->at(index.row()).isDir()) {
                    QPixmap icon = QPixmap(":/img/folder.png");
                    QPixmap tmp = icon.scaled(30, 30, Qt::KeepAspectRatio);
                    value = tmp;
                    break;
                }

                if (this->aDirList->at(index.row()).isFile()) {
                    QString fileExt = this->aDirList->at(index.row()).completeSuffix();

                    if (fileExt == "zip") {

                        QPixmap icon = QPixmap(":/img/zip.png");
                        QPixmap tmp = icon.scaled(30, 30, Qt::KeepAspectRatio);
                        value = tmp;
                        break;

                    }

                    QPixmap icon = QPixmap(":/img/file.png");
                    QPixmap tmp = icon.scaled(30, 30, Qt::KeepAspectRatio);
                    value = tmp;
                    break;
                }

                value = this->aDirList->at(index.row()).fileName();
            }
            break;

            case Qt::UserRole: //data
            {
                value = this->aDirList->at(index.row()).fileName();
            }
            break;

            default:
                break;
        }

    return value;
}

Теперь вам нужно создать архив в папке, где осуществляется сборка проекта, у меня это папка на уровень выше, чем папка с проектом и называется она:

build-QListViewExplorer-Desktop_Qt_MinGW_w64_64bit_MSYS2-Debug

Запускаем:

2020-12-18_12-52-46.png

У архива своя иконка.

Обратите внимание, если у вас имя архива начинается с точки, он не будет нормально обработан, я случайно столкнулся с этим, создавая архив. В принципе с точки начинаются только системные или служебные файлы, так что это не важно.

Таким же образом вы можете добавить иконки для других расширений файлов.

Открываем файлы, как в Проводнике Windows

Попробуем реализовать схожий функционал проводника – запуск/открытие файла при двойном щелчке.

Добавим слот для нашего QListView:

void MainWindow::on_listView_doubleClicked(const QModelIndex &index)
{
    QDesktopServices::openUrl(QUrl(this->aDirList->at(index.row()).absoluteFilePath()));
}

При двойном щелчке на архиве запускается 7-Zip, как и ожидалось.

Добавляем адресную строку

Добавим адресную строку сверху от нашего QListView, чтобы пользователь мог видеть текущий каталог.

На форму добавим компонент LineEdit и разместим его выше QListView.

Добавим в конец конструктора формы строку:

this->ui->lineEdit->setText(QDir::currentPath());

Запустим:

2020-12-18_14-01-56.png

Путь появился в строке.

Меняем текущую папки при двойном щелчке

Давайте добавим функционал перехода в папку, при двойном щелчке на нее.

Изменим метод слота on_listView_doubleClicked()

void MainWindow::on_listView_doubleClicked(const QModelIndex &index)
{
    if (this->aDirList->at(index.row()).isDir())
    {
        QString tmp = this->aDirList->at(index.row()).absoluteFilePath();
        model->getFolderList(this->aDirList->at(index.row()).absoluteFilePath(),this->aDirList);
        this->ui->lineEdit->setText(tmp);
    } else {
        QDesktopServices::openUrl(QUrl(this->aDirList->at(index.row()).absoluteFilePath()));
    }
}

Внесем изменения в метод модели getFolderList() 

void QListViewExplorerModel::getFolderList(QString folderPath, QFileInfoList *dirList)
{
    QDir dir = QDir(folderPath);

    *dirList = dir.entryInfoList(QDir::NoDot | QDir::Files | QDir::Dirs, QDir::DirsFirst);

    this->beginResetModel();
        this->aDirList = dirList;
    this->endResetModel();
}

Запустим.

Теперь вы можете сменить текущую папку, с помощью двойного щелчка по пункту «..» или имени папки.

Рассмотрим получившийся код: 

В слоте по двойному щечку мы проверяем является ли выбранный элемент папкой, если является, то мы вызываем метод модели и заново загружаем элементов список элементов с помощью getFolderList(), но уже для новой папки. Не забываем обновить имя текущей папки в строке адреса.

В методе модели getFolderList(), после того как мы получили список элементов указанной папки мы используем методы beginResetModel() и endResetModel() чтобы уведомить модель о том, что произошел сброс модели, так как данные у нас целиком поменялись.

Переходим на уровень выше с помощью кнопки

Добавим кнопку, чтобы перейти в папку на уровень выше, чем текущая.

На форму добавим кнопку QPushButton.

Назначим ей иконку folderup.png  из ресурса

Удалим в редакторе текст для кнопки, чтобы она использовала иконку.

Добавим к кнопке слот на одиночный щелчок: 

void MainWindow::on_pushButton_clicked()
{
    currentFolder.cdUp();

    this->ui->lineEdit->setText(currentFolder.absolutePath());
    model->getFolderList(currentFolder.absolutePath(),this->aDirList);
}

Изменим конструктор формы:

заменим

    this->model->getFolderList(".",this->aDirList);

на

    this->currentFolder = QDir(QDir::currentPath());

    this->model->getFolderList(this->currentFolder.absolutePath(),this->aDirList);

Добавим в заголовок формы приватное поле

private:
	QDir currentFolder;

Оно нам понадобится, чтобы хранить информацию о текущей папке.

Запускаем. Теперь по щелчку по этой кнопке, мы можем перейти на каталог выше.

Переключаемся между списком и иконками

Доработаем нашу программу еще немного – добавим две кнопки для переключения между отображением списком и иконками.

Добавим две кнопки на форму

Назначим одной иконку из ресурса list.png, а другой iconlist.png

2020-12-18_17-49-12.png

Добавим слоты для кнопок

Для перехода в режим списка:

void MainWindow::on_pushButton_3_clicked()
{
    this->ui->listView->setViewMode(QListView::ListMode);
}

Для перехода в режим иконок:

void MainWindow::on_pushButton_2_clicked()
{
    this->ui->listView->setViewMode(QListView::IconMode);
}

Запускаем:

 2020-12-18_17-51-07.png

При переходе в режим иконок всё съезжает и выглядит очень некрасиво. Доработает методы:

void MainWindow::on_pushButton_3_clicked()
{
    this->ui->listView->setUniformItemSizes(false);
    this->ui->listView->setViewMode(QListView::ListMode);

}

void MainWindow::on_pushButton_2_clicked()
{
    this->ui->listView->setUniformItemSizes(true);
    this->ui->listView->setViewMode(QListView::IconMode);
}

Запускаем:

2020-12-18_17-52-50.png

Уже лучше.

Управляем отображением иконок в окне:

Добавим в конструктор окна строку 

this->ui->listView->setWrapping(true);

Теперь у нас папки отображаются в несколько колонок.

2020-12-19_14-42-46.png

Заменим эту строку на

this->ui->listView->setWordWrap(true);

2020-12-19_14-47-13.png

Имена файлов будут переноситься на новую строку, чтобы вместиться по ширине.

Заключение

Сегодня мы начали создание собственного файлового менеджера, с файлами и папками…

Был создан новый проект, на форму добавлен QListView

Для виджета была создана модель, загружающая элементы в список, используя в качестве источника данных файловую систему.

Настроили сортировку элементов списка таким образом, чтобы папки шли перед файлами.

Добавили иконки в ресурсы проекта.

Доработали модель таким образом, чтобы папки и файлы имели разные иконки.

Реализовали механизм, который при двойном щелчке на файл, открывает так же, как это делает Windows Explorer.

Добавили отдельную иконку для zip-файлов

Добавили кнопку для перехода на папку выше уровнем.

Добавили две кнопки для смены режима отображения между обычным списком и иконками.

Step 1Click New Project, then select Visual C# on the left, then Windows and then select Windows Forms Application. Name your project «FileExplorer» and then click OK

c# file explorerStep 2: Design your form as below

file explorer in c#

Step 3: Add code to handle your form

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace FileExplorer
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void btnOpen_Click(object sender, EventArgs e)
        {
            //Open browser dialog allows you to select the path
            using(FolderBrowserDialog fbd = new FolderBrowserDialog() { Description="Select your path." })
            {
                if (fbd.ShowDialog() == DialogResult.OK)
                {
                    webBrowser.Url = new Uri(fbd.SelectedPath);
                    txtPath.Text = fbd.SelectedPath;
                }
            }
        }

        private void btnBack_Click(object sender, EventArgs e)
        {
            if (webBrowser.CanGoBack)
                webBrowser.GoBack();
        }

        private void btnForward_Click(object sender, EventArgs e)
        {
            if (webBrowser.CanGoForward)
                webBrowser.GoForward();
        }
    }
}

VIDEO TUTORIALS

  • Как создать сетевое подключение в windows 10 через кабель
  • Как создать резервную копию windows акронисом
  • Как создать секретную папку с паролем в windows 10
  • Как создать свой образ системы windows 10
  • Как создать резервную копию windows 7 для восстановления с драйверами и программами