- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在寻找一种很好的方法来解决将 Qt 应用程序移植到 Qt/Necessitas (Android) 的问题。
一些 QtGUI 小部件绝对是残暴的 - 不幸的是,包括 QFileDialog。
您知道有任何外观和感觉合适的替代品吗?是否使 QFileDialog 在 Necessitas 开发人员的高优先级附近可用?
#include <QApplication>
#include <QFileDialog>
int main(int argc, char* argv[]) {
QApplication a(argc, argv);
QString fileName = QFileDialog::getOpenFileName(NULL,
QObject::tr("Open Image"), "/home/jana", QObject::tr("Image Files (*.png *.jpg *.bmp)"));
a.exec();
}
最佳答案
Android 没有自己的本地文件对话框。我们可以使用 QtAndroidExtras 来调用能够选择文件的外部应用程序:
我写了 wrapper,可以用来做那个。这是完整的代码:
android文件对话框.h
#ifndef ANDROIDFILEDIALOG_H
#define ANDROIDFILEDIALOG_H
#include <QObject>
#include <QAndroidJniObject>
#include <QtAndroid>
#include <QAndroidActivityResultReceiver>
class AndroidFileDialog : public QObject
{
Q_OBJECT
public:
explicit AndroidFileDialog(QObject *parent = 0);
virtual ~AndroidFileDialog();
bool provideExistingFileName();
private:
class ResultReceiver : public QAndroidActivityResultReceiver {
AndroidFileDialog *_dialog;
public:
ResultReceiver(AndroidFileDialog *dialog);
virtual ~ResultReceiver();
void handleActivityResult(int receiverRequestCode, int resultCode, const QAndroidJniObject &data);
QString uriToPath(QAndroidJniObject uri);
};
static const int EXISTING_FILE_NAME_REQUEST = 1;
ResultReceiver *receiver;
void emitExistingFileNameReady(QString result);
signals:
void existingFileNameReady(QString result);
};
#endif // ANDROIDFILEDIALOG_H
android文件对话框.cpp
#include "androidfiledialog.h"
AndroidFileDialog::ResultReceiver::ResultReceiver(AndroidFileDialog *dialog) : _dialog(dialog) {}
AndroidFileDialog::ResultReceiver::~ResultReceiver() {}
void AndroidFileDialog::ResultReceiver::handleActivityResult(int receiverRequestCode, int resultCode, const QAndroidJniObject &data)
{
jint RESULT_OK = QAndroidJniObject::getStaticField<jint>("android/app/Activity", "RESULT_OK");
if (receiverRequestCode == EXISTING_FILE_NAME_REQUEST && resultCode == RESULT_OK) {
QAndroidJniObject uri = data.callObjectMethod("getData", "()Landroid/net/Uri;");
QString path = uriToPath(uri);
_dialog->emitExistingFileNameReady(path);
} else {
_dialog->emitExistingFileNameReady(QString());
}
}
QString AndroidFileDialog::ResultReceiver::uriToPath(QAndroidJniObject uri)
{
if (uri.toString().startsWith("file:", Qt::CaseInsensitive)) {
return uri.callObjectMethod("getPath", "()Ljava/lang/String;").toString();
} else {
QAndroidJniObject contentResolver = QtAndroid::androidActivity().callObjectMethod("getContentResolver", "()Landroid/content/ContentResolver;");
QAndroidJniObject cursor = contentResolver.callObjectMethod("query", "(Landroid/net/Uri;[Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;)Landroid/database/Cursor;", uri.object<jobject>(), 0, 0, 0, 0);
QAndroidJniObject DATA = QAndroidJniObject::fromString("_data");
jint columnIndex = cursor.callMethod<jint>("getColumnIndexOrThrow", "(Ljava/lang/String;)I", DATA.object<jstring>());
cursor.callMethod<jboolean>("moveToFirst", "()Z");
QAndroidJniObject result = cursor.callObjectMethod("getString", "(I)Ljava/lang/String;", columnIndex);
return result.isValid() ? result.toString() : QString();
}
}
AndroidFileDialog::AndroidFileDialog(QObject *parent) : QObject(parent)
{
receiver = new ResultReceiver(this);
}
AndroidFileDialog::~AndroidFileDialog()
{
delete receiver;
}
bool AndroidFileDialog::provideExistingFileName()
{
QAndroidJniObject ACTION_GET_CONTENT = QAndroidJniObject::fromString("android.intent.action.GET_CONTENT");
QAndroidJniObject intent("android/content/Intent");
if (ACTION_GET_CONTENT.isValid() && intent.isValid()) {
intent.callObjectMethod("setAction", "(Ljava/lang/String;)Landroid/content/Intent;", ACTION_GET_CONTENT.object<jstring>());
intent.callObjectMethod("setType", "(Ljava/lang/String;)Landroid/content/Intent;", QAndroidJniObject::fromString("file/*").object<jstring>());
QtAndroid::startActivity(intent.object<jobject>(), EXISTING_FILE_NAME_REQUEST, receiver);
return true;
} else {
return false;
}
}
void AndroidFileDialog::emitExistingFileNameReady(QString result)
{
emit existingFileNameReady(result);
}
你必须添加到你的 *.pro 文件:
QT += androidextras
使用示例:
AndroidFileDialog *fileDialog = new AndroidFileDialog();
connect(fileDialog, SIGNAL(existingFileNameReady(QString)), this, SLOT(openFileNameReady(QString)));
bool success = fileDialog->provideExistingFileName();
if (!success) {
qDebug() << "Problem with JNI or sth like that...";
disconnect(fileDialog, SIGNAL(existingFileNameReady(QString)), this, SLOT(openFileNameReady(QString)));
//or just delete fileDialog instead of disconnect
}
插槽实现:
void MyClass::openFileNameReady(QString fileName)
{
if (!fileName.isNull()) {
qDebug() << "FileName: " << fileName;
} else {
qDebug() << "User did not choose file";
}
}
请确认此解决方案在您的设备上正常工作。
关于android - Qt/Necessitas - 合理的 QFileDialog 替换/皮肤?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15079406/
我正在尝试为必须对给定文件执行某些操作的程序编写 GUI。它的逻辑是: 1) 程序从创建一个文本字段和一个按钮开始。 2) 如果我点击按钮,我可以选择一些.exe 文件。如果选择文件,其路径将设置为与
我是 QT 的新手。目前在我的项目中我实现了 QFileDialog . 在我的用例中:每当用户选择一个文本文件时,它都会执行 functionA .但是,我发现如果在文件对话框中单击取消,funct
我尝试了以下操作来打开一个应该显示用户主目录的文件对话框: QString fileName = QFileDialog::getOpenFileName(this,
我试图在我的 PySide2 应用程序中打开一个文件,但文件对话框总是在主窗口下方打开,并在启动器中显示为另一个应用程序。应用程序的名称是“门户”。 我看到other answers其中解决方案是将主
我想创建一个 QFileDialog 的子类,它将用于仅打开具有某些特定内容的目录。我可以设置我自己的代理模型来处理文件列表的行为,但是如何禁用/启用确定按钮? 我必须创建自己的小部件吗? 最佳答案
1)我想获取文件夹监控应用程序的文件夹名称.. 有没有办法可以过滤掉使用 QFileDialog 显示的特定文件夹(例如,我不希望我的文档显示在文件对话框中)。 2)我不希望用户选择驱动器。默认情况下
我想建立一个类似于 QFileDialog::getExistingDirectory() 的对话框仅当所选目录包含某些文件时才启用确定按钮。 我知道我无法通过 QFileDialog 实现这一目标,
我使用下面的代码来构建文件名的 qstringlist: QStringList filenames = QFileDialog::getOpenFileNames(this,"",QDir::cur
QFileDialog 在我的代码中使用如下: QFileDialog fileDlg; fileDlg.setFileMode(QFileDialog::AnyFile); fileDlg.setV
我想打开一个包含所有支持的图像格式的 QFileDialog.getOpenFileName(我可以用来实例化 QIcon 的所有文件类型) 我已经知道我可以使用 QImageReader.suppo
关闭 QFileDialog.getSaveFileName 时遇到问题。如果我选择取消而不继续保存文件,我的程序就会崩溃。 我知道该语句将始终为 True,因为 getSaveFileName()
我想将选定文件的位置存储为 Python 中的字符串。我正在尝试使用 QFileDialog 来完成此任务,我有: self.filedialog = QtGui.QFileDialog(self)
我遇到了一个问题,当我选择不保存文件并单击系统窗口上的“取消”时,程序将崩溃。这是我收到的错误: Traceback (most recent call last): File "BasicEmail
我有一个 QFileDialog 对象,我需要用户在其中选择一个目录 QFileDialog dlg(this, tr("Select directory")); dlg.setDirectory(c
我同时使用 QFileDialog getOpenFileName 和 getSaveFileName。我在网络上有一个文件(连接速度慢),我使用 getOpenFileName 加载它。然后,如果我
我在 Qt 中有一个用于保存文件的 QFileDialog。 它不是 smmiting 信号。我通过连接它 QFileDialog diag(this); ... connect( d
我正在开发一个项目,我正在使用 Python 和 PyQT4 进行开发。我偶然发现了 QFileDialog 的一个有点奇怪的行为,在我的 IDE (Eclipse) 中运行项目时不会发生这种行为。
我想使用 QFileDialog 获取新目录的名称,我将在其中创建几个配置文件。 如果目录名不包含扩展部分就好了。我如何强制用户不提供带有 filename.extension 的 QFileDial
我在 Qt 5.2 中使用 QFileDialog 时遇到一点问题。当我打开对话框时,对话框会出现,但不会将任何选定的文件发回给我。在下面的代码示例中,“selectedFiles.at(0)”没有提
我正在尝试使用 QFileDialog 获取文件路径,编译很顺利,但是当我从应用程序打开对话框时,会弹出此窗口: 看起来路径中缺少字母“á”。 即使我尝试从快速访问中打开桌面,它也会弹出(顺便说一句。
我是一名优秀的程序员,十分优秀!