Russian Qt Forum
Апрель 28, 2024, 13:06 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: отображение примонтированых устройств  (Прочитано 5519 раз)
koldun90
Крякер
****
Offline Offline

Сообщений: 345


Просмотр профиля
« : Июль 12, 2014, 07:52 »

Здравствуйте скажите вот допустим когда я отображаю модель в линуксе

Код:
model1=new QFileSystemModel();
model1->setRootPath(QDir::currentPath());
model1->setFilter(QDir::AllDirs | QDir::Files |QDir::NoDotAndDotDot);
model1->setReadOnly(false);
 
ui->treeview->setModel(model1)


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

А в линуксе отображается только каталог "/mnt".

Так что мне нужно сделать чтобы в линуксе файловая модель отображалась также как и в windows 7?
Мне вообще нужно сделать так чтоб в линуксе отображался каталог ("/"),а затем чуть ниже вставленная флешка( ее метка тома)
и допустим другие диски.
Подскажите что нужно переопределять и тд итп...

p.s вроде можно использовать dbus, но какие конкретно использовать(методы библиотеки) я не знаю
Записан
Командор
Гость
« Ответ #1 : Июль 12, 2014, 13:14 »

Здравствуйте! Да, нужно использовать dbus (или hal, но в линуксе он практически везде выпилен).
Я делал так:

Код
C++ (Qt)
#include <QtDBus>
#define UD_DBUS_SERVICE                 "org.freedesktop.UDisks"
#define UD_DBUS_PATH                    "/org/freedesktop/UDisks"
#define UD_DBUS_INTERFACE_DISKS         "org.freedesktop.UDisks"
#define UD_DBUS_INTERFACE_DISKS_DEVICE  "org.freedesktop.UDisks.Device"
#define UD_DBUS_DEVICES_PREFIX          "/org/freedesktop/UDisks/devices/"
 
void DeviceManager::getData()
{
   QDBusInterface* UDisksInterface = new
           QDBusInterface(UD_DBUS_SERVICE, UD_DBUS_PATH,
                          UD_DBUS_INTERFACE_DISKS,
                          QDBusConnection::systemBus(), this);
 
   QDBusReply <QList <QDBusObjectPath> > objectPathList = UDisksInterface->call("EnumerateDevices");
   if (objectPathList.isValid()) {
       foreach (QDBusObjectPath pathDevice, objectPathList.value()) {
           QDBusInterface deviceInterface(UD_DBUS_SERVICE, pathDevice.path(),
                                          UD_DBUS_INTERFACE_DISKS_DEVICE,
                                          QDBusConnection::systemBus(), this);
           QVariant idUsage = deviceInterface.property("IdUsage");
           if (idUsage.isValid()) {
               if (idUsage.toString() == "filesystem") {
                   devicePathList << pathDevice.path().section('/', -1);
                   mountPathList << deviceInterface.property("DeviceMountPaths").toString();
                   QVariant idType = deviceInterface.property("IdType");
                   if (idType.isValid())
                       fileSystemList << idType.toString();
                   else
                       fileSystemList << "";
                   QVariant idLabel = deviceInterface.property("IdLabel");
                   if (idLabel.isValid()) {
                       if (!idLabel.toString().isEmpty()) {
                           labelDiskList << idLabel.toString();
                           diskNameList << idLabel.toString();
                       }
                       else {
                           labelDiskList << "";
                           diskNameList << devicePathList.last();
                       }
                   }
                   QVariant deviceIsHard = deviceInterface.property("DeviceIsSystemInternal");
                   if (deviceIsHard.isValid()) {
                       if (deviceIsHard.toBool()) {
                           typeDiskList << "drive-harddisk";
                       }
                       else {
                           QVariant deviceIsDrive = deviceInterface.property("DeviceIsDrive");
                           if (deviceIsDrive.isValid()) {
                               if (deviceIsDrive.toBool()) {
                                   QVariant driveMediaCompatibility = deviceInterface.property("DriveMediaCompatibility");
                                   if (driveMediaCompatibility.isValid()) {
                                       QStringList mediaTypes = driveMediaCompatibility.toStringList();
                                       if (!mediaTypes.filter("optical").isEmpty())
                                           typeDiskList << "media-optical";
                                       else if (!mediaTypes.filter("flash").isEmpty())
                                           typeDiskList << "drive-removable-media-usb-pendrive";
                                       else if (!mediaTypes.filter("floppy").isEmpty())
                                           typeDiskList << "media-floppy";
                                       else
                                           typeDiskList << "drive-harddisk";
                                   }
                               }
                               else {
                                   if (deviceInterface.property("DriveConnectionInterface").toString() == "usb")
                                       typeDiskList << "drive-removable-media-usb-pendrive";
                                   else
                                       typeDiskList << "drive-harddisk";
                               }
                           }
                       }
                   }
               }
           }
       }
 

После этого нужно как-то списки devicePathList, typeDiskList , labelDiskList прокинуть в модель.
У меня она самопальная, так что проще. А вот как быть с QFileSystemModel не знаю, наверное, нужно наследоваться и переопределять  QVariant data ( const QModelIndex & index, int role = Qt::DisplayRole ), допустим, если index указывает на корень, то отобразить корень и, например, labelDiskList (при этом отобразиться либо метка либо название устройства sda..).

А что за файл-менеждер, если не секрет? Каковы цели, возможности, открытый/закрытый или просто потренироваться? А то я тоже делаю файл-менеждер. Впрочем, я пошел иначе, отказался не только от QFileSystemModel, но и от Qt-х вьюверов, слабоваты они.
Записан
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4727



Просмотр профиля WWW
« Ответ #2 : Июль 12, 2014, 13:15 »

model1->setRootPath("/");
Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
Командор
Гость
« Ответ #3 : Июль 12, 2014, 13:22 »

model1->setRootPath("/");

В этом случае просто отобразиться корень файловой системы. А человеку нужно как в Dolphin, например. Т.е. чтобы отдельно отобразились разделы, сидюки, флешки и т.д. При этом нужно, чтобы флешку можно было примонтировать/отмонтировать.
Записан
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4727



Просмотр профиля WWW
« Ответ #4 : Июль 12, 2014, 14:16 »

к сожалению, в линуксе не силен Улыбающийся
Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
Bepec
Гость
« Ответ #5 : Июль 12, 2014, 14:42 »

Файловая система винды - это структурированное разбиение на "диски/приводы и прочая".
Файловая система linux - хрен знает что с общим корнем и содержимым без особой структуры.

Так что чтобы отобразить разделы сидюки и флешки, вам нужно самому анализировать и отображать это. Приводя хаотический общий корень в упорядоченную структуру.
Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #6 : Июль 12, 2014, 15:28 »

ТС, попробуй этот класс: https://codereview.qt-project.org/#/c/73945/
Записан

ArchLinux x86_64 / Win10 64 bit
vbv
Чайник
*
Offline Offline

Сообщений: 59


Просмотр профиля
« Ответ #7 : Июль 12, 2014, 18:39 »

Во первых: структуры файловых систем разные.
    И таким образом "в лоб" так сделать не получится.

Как варианты:
1. Унаследовать модель и на основании монтирования вынести части fs в корень модели.
2. Поставить proxymodel в которой сделать преобразования как в п.1.
3. сделать окно из 2-х частей где дополнительно будут отображаться точки монтирования
при клике на которые будет производится монтирование/размонтирование и переход в этом место fs в модели и TreeView/TreeWidget соответственно.

По другому не вижу, как этом можно реализовать.
Хотя можно полностью реализовать свою модель.

Не по вопросу:
PS: Как по мне так, *nix структура гораздо эффективнее и понятнее чем форточная. И когда я вижу подобного рода реализации - вызывает аллергию.
Ну как может находится точка входа в VFS, ниже корня самой файловой системы.
Попадая под форточки - это немножко бесит.

Пример:
Монтирован /home  и у меня в домашнем подкаталоге есть каталог ~/home - глядя на подобное представление - вопрос так в каком же месте фс я в данный момент нахожусь?
И в результате приходиться спускаться от root (/) например что-бы попасть в /home/tmp а не в ~/tmp (есть у меня и такие подкаталоги.) или на оборот. А если я уже в tmp где мне потом искать сохраненный файл, т.е. нужно подняться на уровень вверх и посмотреть, куда же я таки сохраняю данные.
А в модели можно вынести в корень только, точки монтирования, как ссылки к реальной mountpoint - хотя это и есть /mnt.
Или реализовать механизм Bookmark где выставлять желаемые, быстрые точки входа в фс.
Как вариант, даже можно перемонтировать mnt в ~/mnt.

И еще, эта мулечка, которя монтирует в /media - совсем страшная штука. Черти куда цепляет диск, и где его искать.....
Пример: под кедами монтируется диск и подключается в авто-подключении /media/чего-то/там. Надо открыть dolphin'ом посмотреть куда же его таки прицепило сие несчастье и после этого в консоле cd /media/чего-то/там.... Ну в самом деле это не вариант. Причем методов авто-монтирования - тьма. А точки входа можно увидеть только как результат выполнения mount из консоли. Ну или путем "прямо спросить у ядра" через API.
Записан
Bepec
Гость
« Ответ #8 : Июль 12, 2014, 19:52 »

to vdv: вы определитесь.
Вас воротит от Win реализации, а доводы о безумности вы приводите с Unix реализацией Веселый
Записан
vbv
Чайник
*
Offline Offline

Сообщений: 59


Просмотр профиля
« Ответ #9 : Июль 13, 2014, 06:20 »

to vdv: вы определитесь.
Вас воротит от Win реализации, а доводы о безумности вы приводите с Unix реализацией Веселый

to:Bepec
Не подворачивайте пожалуйста.
Против *nix реализации я ничего не имею, я имею "против" втягивания в *nix системы видновой реализации.
Второе: система автомонтирования - это отдельная песня. т.к. Монтируем автоматом, отмонтируем руками...
Плюс я написал как получать точки монтирования, а не о самом механизме монтажа.
К тому-же к самому вопросу, это уже не относится - "Хочешь делай".
А доводы о по Вашему "безумности Unix" я не привожу, а утверждаю о не корректности под *nix ориентироваться на какой-то один принцип автомонтирования. Который опирается на дополнения. Или придется требовать зависимости от сторонних библиотек и опираться на их функции. Причем нет гарантии, что эти библиотеки окажутся на клиентской машине предустановленны. Тем более не ориентироваться на автомонтирование через DE (KDE и пр.).
А в общем случае, систем автомонтирования много и для разных целей используются разные. (пример: монтаж ресурса на сервере и отключении его по завершению работы с ним, против пользовательской сессии когда сам пользователь решает когда нужен ему этот ресурс когда уже нет)

PS:
монтирую по прежнему:
mount /dev/sda1 /mnt
а размонтирую по прежнему:
umount /mnt
и смотрю, чего намонтировано:
mount
И проблем нет, и все нравится.
Записан
koldun90
Крякер
****
Offline Offline

Сообщений: 345


Просмотр профиля
« Ответ #10 : Июль 13, 2014, 11:49 »

Здравствуйте! Да, нужно использовать dbus (или hal, но в линуксе он практически везде выпилен).
Я делал так:

Код
C++ (Qt)
#include <QtDBus>
#define UD_DBUS_SERVICE                 "org.freedesktop.UDisks"
#define UD_DBUS_PATH                    "/org/freedesktop/UDisks"
#define UD_DBUS_INTERFACE_DISKS         "org.freedesktop.UDisks"
#define UD_DBUS_INTERFACE_DISKS_DEVICE  "org.freedesktop.UDisks.Device"
#define UD_DBUS_DEVICES_PREFIX          "/org/freedesktop/UDisks/devices/"
 
void DeviceManager::getData()
{
   QDBusInterface* UDisksInterface = new
           QDBusInterface(UD_DBUS_SERVICE, UD_DBUS_PATH,
                          UD_DBUS_INTERFACE_DISKS,
                          QDBusConnection::systemBus(), this);
 
   QDBusReply <QList <QDBusObjectPath> > objectPathList = UDisksInterface->call("EnumerateDevices");
   if (objectPathList.isValid()) {
       foreach (QDBusObjectPath pathDevice, objectPathList.value()) {
           QDBusInterface deviceInterface(UD_DBUS_SERVICE, pathDevice.path(),
                                          UD_DBUS_INTERFACE_DISKS_DEVICE,
                                          QDBusConnection::systemBus(), this);
           QVariant idUsage = deviceInterface.property("IdUsage");
           if (idUsage.isValid()) {
               if (idUsage.toString() == "filesystem") {
                   devicePathList << pathDevice.path().section('/', -1);
                   mountPathList << deviceInterface.property("DeviceMountPaths").toString();
                   QVariant idType = deviceInterface.property("IdType");
                   if (idType.isValid())
                       fileSystemList << idType.toString();
                   else
                       fileSystemList << "";
                   QVariant idLabel = deviceInterface.property("IdLabel");
                   if (idLabel.isValid()) {
                       if (!idLabel.toString().isEmpty()) {
                           labelDiskList << idLabel.toString();
                           diskNameList << idLabel.toString();
                       }
                       else {
                           labelDiskList << "";
                           diskNameList << devicePathList.last();
                       }
                   }
                   QVariant deviceIsHard = deviceInterface.property("DeviceIsSystemInternal");
                   if (deviceIsHard.isValid()) {
                       if (deviceIsHard.toBool()) {
                           typeDiskList << "drive-harddisk";
                       }
                       else {
                           QVariant deviceIsDrive = deviceInterface.property("DeviceIsDrive");
                           if (deviceIsDrive.isValid()) {
                               if (deviceIsDrive.toBool()) {
                                   QVariant driveMediaCompatibility = deviceInterface.property("DriveMediaCompatibility");
                                   if (driveMediaCompatibility.isValid()) {
                                       QStringList mediaTypes = driveMediaCompatibility.toStringList();
                                       if (!mediaTypes.filter("optical").isEmpty())
                                           typeDiskList << "media-optical";
                                       else if (!mediaTypes.filter("flash").isEmpty())
                                           typeDiskList << "drive-removable-media-usb-pendrive";
                                       else if (!mediaTypes.filter("floppy").isEmpty())
                                           typeDiskList << "media-floppy";
                                       else
                                           typeDiskList << "drive-harddisk";
                                   }
                               }
                               else {
                                   if (deviceInterface.property("DriveConnectionInterface").toString() == "usb")
                                       typeDiskList << "drive-removable-media-usb-pendrive";
                                   else
                                       typeDiskList << "drive-harddisk";
                               }
                           }
                       }
                   }
               }
           }
       }
 

После этого нужно как-то списки devicePathList, typeDiskList , labelDiskList прокинуть в модель.
У меня она самопальная, так что проще. А вот как быть с QFileSystemModel не знаю, наверное, нужно наследоваться и переопределять  QVariant data ( const QModelIndex & index, int role = Qt::DisplayRole ), допустим, если index указывает на корень, то отобразить корень и, например, labelDiskList (при этом отобразиться либо метка либо название устройства sda..).

А что за файл-менеждер, если не секрет? Каковы цели, возможности, открытый/закрытый или просто потренироваться? А то я тоже делаю файл-менеждер. Впрочем, я пошел иначе, отказался не только от QFileSystemModel, но и от Qt-х вьюверов, слабоваты они.
здравствуйте я монтирую командой mount /mnt
Работаю в мсвс
файл менеджер почти доделал (осталось вот реализовать показ примонтированых устройств )
если можно отправьте вашу почту или скайп для связи с вами в личку
« Последнее редактирование: Июль 13, 2014, 12:58 от koldun90 » Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.118 секунд. Запросов: 23.