2014-10-20 17 views
9

Come ho capito, il modo di confezionare le risorse non di codice come i file di dati in un'app Qt sta utilizzando il sistema di risorse. Tuttavia, cosa succede se voglio accedere a una risorsa utilizzando una funzione non Qt. Ad esempio, potrei avere un file .txt o .csv con alcuni dati dell'applicazione a cui voglio accedere utilizzando ifstream. Non sembra funzionare per utilizzare la sintassi ": ..." al posto di un nome file per funzioni e classi non Qt. Esiste un flusso di lavoro separato per i dati di imballaggio utilizzati dalle funzioni non Qt in un'app?Come accedere ai dati delle risorse Qt da funzioni non-QI

Sto usando OSX, ma suppongo che questi problemi siano indipendenti dalla piattaforma.

+0

possibile duplicato di [? Come usare un qfile con std :: iostream] (http://stackoverflow.com/questions/5204335/how-to- use-a-qfile-with-stdiostream) – HostileFork

+0

Poiché le risorse Qt sono compresse nell'eseguibile stesso, l'unico modo per farlo funzionare è estrarre il file in una cartella temporanea in modo che il codice non-Qt possa usarlo. – sjdowling

+0

Scrive una funzione o classe che collega il codice Qt e quello non-Qt. Quindi chiama quella funzione (invoca i metodi di quella classe) dal codice non-Qt. –

risposta

4

L'unico scopo del sistema di risorse Qt è quello di raggruppare i dati all'interno dell'eseguibile stesso. Se si desidera non integrare i dati nell'eseguibile, è sufficiente non utilizzare il sistema di risorse.

su Mac, se si desidera aggiungere "data.txt" dalla sorgente del progetto al vostro pacchetto di applicazioni, ma non per l'eseguibile stesso, aggiungere il seguente al vostro file di .pro:

mac { 
    BUNDLE = $$OUT_PWD/$$TARGET$$quote(.app)/Contents 
    QMAKE_POST_LINK += ditto \"$$PWD/data.txt\" \"$$BUNDLE/Resources/\"; 
} 

ciò premesso file di progetto, utilizzare il QCoreApplication::applicationDirPath() per un percorso utile a ottenere al file:

#include <QCoreApplication> 
#include <QFile> 
#include <QDebug> 

int main(int argc, char *argv[]) 
{ 
    QCoreApplication a(argc, argv); 
    qDebug() << QCoreApplication::applicationDirPath(); 
    QFile data(QCoreApplication::applicationDirPath() + "/../Resources/data.txt"); 
    if (data.open(QIODevice::ReadOnly | QIODevice::Text)) 
     qDebug() << data.readAll(); 
    return 0; 
} 

nell'esempio precedente, la cartella Resources ha nulla a che fare con la risorsa syst Qt em. È semplicemente una convenzione di denominazione nei pacchetti di applicazioni OS X. Non stiamo usando il sistema di risorse Qt qui.

Se si desidera utilizzare il sistema di risorse Qt e accedere direttamente ai dati della risorsa e non tramite uno QFile, la classe QResource fornisce l'accesso alle risorse incluse nell'eseguibile.

Se il codice sotto il tuo controllo insiste sull'uso di ifstream per l'immissione dei dati, è artificialmente limitato e dovrebbe essere corretto. Dovrebbe invece usare istream, dato che quella classe può essere supportata da qualsiasi cosa, non necessariamente da un file. Se si tratta di codice che non si controlla, è possibile impostare lo ifstream su un QLocalSocket.

È possibile mappare la costante QResource::data()to an input stream tramite un buffer di flusso.

Se la risorsa isCompressed(), è necessario prima decomprimerlo in un'area temporanea. È anche possibile disable resource compression per evitare il passaggio di decompressione. È possibile utilizzare un compressore eseguibile per intero come upx - al momento dell'esecuzione del codice, tutto sarà già decompresso e pronto per l'uso.

+0

Che cosa fa "ditto"? – daj

+0

@daj "idem - copia le gerarchie di directory, crea ed estrai archivi" Dato che sei su OS X, scrivi semplicemente "man ditto" nel terminale per vedere la documentazione. –

1

Qt produce file grandi qrc_*.cpp che vengono compilati in un file eseguibile se li si dichiara nel file .pro come RESOURCES = myResources.qrc. Quindi in questo caso puoi accedervi solo nella tua app Qt.

Tuttavia, se si può influenzare il codice risorse di carico si può non compilare le risorse-in, ma caricarli esplicitamente in runtime con

QResource::registerResource("/path/to/myResources.rcc") 

e felicemente leggerli dal disco come file normali.

+1

Questo non risponde alla domanda. –

0

Che ne dici di aprire il file di risorse con un oggetto QFile, avvolgendolo con un oggetto QDataStream e avvolgendolo con un oggetto boost :: iostreams :: stream, che deriva da una specializzazione di std :: basic_istream? Sembra complicato, ma non richiede troppe righe di codice, vedi this answer.

1

È possibile copiare il file di risorse in una cartella temporanea. Per fare questo, usa un QTemporaryDir che crea una cartella temporanea e la cancella automaticamente quando il programma è finito. Per accedere al percorso di tale cartella, utilizzare il metodo QTemporaryDir::path(). Ecco un esempio di come si può utilizzare:

#include <QTemporaryDir> //You need to include this header 
QTemporaryDir temporaryDir; 
//Copy the resource file into the temporary folder 
QFile::copy(":/exampleprefix/examplefile.txt", temporaryDir.path() + "/examplefile.txt"); 
//Read the file 
std::ifstream fileStream(QString(temporaryDir.path() + "/examplefile.txt").toLatin1().data()); 
//etc 
Problemi correlati