2013-02-26 17 views
5

Ich bin auf der Suche nach einer netten Möglichkeit, Qt-Anwendungen auf Qt/Necessitas (Android) zu portieren.Qt/Necessitas - angemessener QFileDialog Ersatz/Haut?

Einige der QtGUI-Widgets sind absolut scheußlich - leider inklusive QFileDialog.

Kennen Sie irgendwelche Ersatzteile mit einem korrekten Aussehen und Gefühl? Macht QFileDialog für Necessitas-Entwickler irgendwo eine hohe Priorität?

#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(); 
} 

QFileDialog

+0

Was meinst du - grausam ?? Dieser ist absolut glatt! – mlvljr

Antwort

1

Sie ganz einfach Ihren eigenen Datei-Dialog entweder mit QtWidgets oder QML, mithilfe der Out-of-the-box QFileSystemModel Klasse bauen könnten.

Ob es Priorität hat oder nicht, an dieser Stelle scheint es, dass Necessitas von Digias Bemühungen, Android zu unterstützen, absorbiert wird. Ich bezweifle, dass es erhebliche Anstrengungen geben wird, QtWidgets passend zu stylen, da das Modul als FERTIG markiert ist und der gesamte Fokus für die Benutzeroberfläche auf QML liegt. Also würde ich nicht mit dem Atem anhalten, wenn ich du wäre. Außerdem sehen die Qt-Widgets auf den Desktop-Plattformen völlig hässlich aus.

3

Android hat keinen eigenen, nativen Dateidialog. Wir können QtAndroidExtras nutzen externe Anwendung aufzurufen, die eine Datei zu holen ist in der Lage:

chosing external application

ich Wrapper geschrieben, die für diese verwendet werden könnten. Hier ist voll Code:

androidfiledialog.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 

androidfiledialog.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); 
} 

Sie müssen Ihre * .pro-Datei hinzufügen:

QT += androidextras 

mit Beispiel:

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 
} 

Slot Implementierung:

void MyClass::openFileNameReady(QString fileName) 
{ 
    if (!fileName.isNull()) { 
     qDebug() << "FileName: " << fileName; 
    } else { 
     qDebug() << "User did not choose file"; 
    } 
} 

Bitte bestätigen Sie diese Lösung richtig auf Ihrem Gerät funktioniert.

Verwandte Themen