QT MAC下文件文件夹混合多选对话框解决方案

问题描述

由于QFileDialog仅支持多选文件或者单选目录,但是有些场景又需要文件文件夹混合多选。

Qt文档

The QFileDialog class enables a user to traverse the file system in order to select one or many files or a directory.

机翻

QFileDialog 类使用户能够遍历文件系统以选择一个或多个文件或目录。

解决方案

使用mac下系统对话框

macfiledialog.mm

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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#include "macfiledialog.hpp"

#include <QStringList>

#import <Appkit/NSOpenPanel.h>
#import <Foundation/Foundation.h>


QStringList getMacFiles(QWidget *widget)
{
auto *nsView = reinterpret_cast<NSView *>(widget->winId());
NSWindow *nsWindow = [nsView window];
if (!nsWindow) {
qWarning("Failed to get native NSWindow from QWidget");
return {};
}

QStringList files;
NSMutableArray *fileURLArray = [[NSMutableArray alloc] init];

NSOpenPanel *panel = [NSOpenPanel openPanel];
[panel setCanChooseDirectories:YES];
[panel setCanChooseFiles:YES];
[panel setCanCreateDirectories:YES];
[panel setAllowsMultipleSelection:YES];
[panel setResolvesAliases:YES];

static QEventLoop loop;

//界面出现在电脑屏幕中央
[panel beginSheetModalForWindow:nsWindow completionHandler:^(NSInteger result) {
if (result == NSModalResponseOK) {
NSLog(@"OK");
for (NSURL *url in [panel URLs]) {
NSString *path = [NSString stringWithString:[url path]];
//path = [path stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
//path = [path stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
[fileURLArray addObject:path];
//NSLog(@"%@", path);
}

NSLog(@"%@", fileURLArray);
} else if (result == NSModalResponseCancel) {
NSLog(@"Cancel");
} else if (result == NSModalResponseStop) {
NSLog(@"Stop");
}
loop.quit();
}];

loop.exec();
for (NSString *a in fileURLArray) {
files.append(QString::fromNSString(a));
}
return files;
}

pro

1
2
3
4
5
6
7
8
mac{
HEADERS += $$PWD/macdialog.hpp
SOURCES += $$PWD/macdialog.mm

LIBS += \
-framework AppKit \
-framework CoreFoundation
}