I have been creating an application in qt. I have added open function in it, but was happening that when I open an already open file, it again opens the same file instead of pointing it to already opened file.
void MainWindow::actionOpen()
{
QFileInfo fileInfo = UIUtils::openFile(this);
if (!fileInfo.exists()) {
return;
}
if (!MainWindow::mdiMode && !maybeSave()) {
return;
}
openFile(fileInfo.filePath());
}
Please help me to solve the problem.
I'm not 100 % clear on what the issue is, but if you don't want to run the openFile function on files you've previously opened, you have to keep a record.
For instance, define a QList in your header file:
QList<QFileInfo> knownFiles;
And then keep it up to date and check it:
void MainWindow::actionOpen()
{
QFileInfo fileInfo = UIUtils::openFile(this);
if (!fileInfo.exists()) {
return;
}
if (!MainWindow::mdiMode && !maybeSave()) {
return;
}
bool fileIsKnown = false;
for(qint64 i=0; i<knownFiles.length(); i++)
if(knownFiles.at(i) == fileInfo)
{
fileIsKnown = true;
break;
}
if(!fileIsKnown)
{
knownFiles << fileInfo;
openFile(fileInfo.filePath());
}
}
I don't know what you mean when you say "instead of pointing it to already opened file.".
Related
I am working on creating zip archive using old Qt - ZipWriter class. The problem is when I want to add the directory. The default Qt code for addDirectory method - d->addEntry(ZipWriterPrivate::Directory, archDirName, QByteArray());. It does not add any content, only the empty directory. So, I have improved it to add the directories and content as well.
My code:
QList<QString> dirs;
int recursion = 0;
void ZipWriter::addDirectory(const QString &dirPath)
{
QDir archDir(dirPath);
archDir.setFilter(QDir::AllEntries | QDir::NoDotAndDotDot);
dirs << addDirSeparator(archDir.dirName());
if (archDir.exists()) {
QString archDirName = "";
if (recursion > 0) {
for (int i = recursion; i < dirs.count(); i++) {
archDirName = dirs.first().append(dirs.at(i));
}
} else {
archDirName = dirs.at(recursion);
}
if (!archDir.isEmpty()) {
const QStringList archFileList = archDir.entryList();
if (archFileList.count() > 0) {
for (QString archFile : archFileList) {
QFileInfo archFileInfo(QDir::toNativeSeparators(QString("%1/%2").arg(archDir.absolutePath(), archFile)));
if (archFileInfo.isDir()) {
recursion++;
addDirectory(archFileInfo.absoluteFilePath());
} else {
QFile zipFile(archFileInfo.absoluteFilePath());
zipFile.open(QIODevice::ReadOnly);
addFile(QString("%1%2").arg(archDirName, archFile), zipFile.readAll());
zipFile.close();
}
}
}
} else {
d->addEntry(ZipWriterPrivate::Directory, archDirName, QByteArray());
}
}
}
Now, it adds the directory and content recursively but it has issue when directory is on the same level, it appends it to the end. I think, I must use the STL container to keep track of the directory for example QMap but the question is how to get the current directory level? Any ideas? Thank you.
Updated: 01.05.2022
I have change my code to this:
void ZipWriter::addDirectory(const QString &dirPath)
{
QDirIterator dirIt(dirPath, QDir::AllEntries | QDir::NoDotAndDotDot, QDirIterator::Subdirectories);
while (dirIt.hasNext()) {
QString archDirPath = dirIt.next();
QFile zipFile(archDirPath);
zipFile.open(QIODevice::ReadOnly);
if (!dirIt.fileInfo().isDir()) {
addFile(archDirPath, zipFile.readAll());
}
zipFile.close();
}
}
It adds everything recursively and in correct order but I have another issue. Now, it adds the full path to the archive. For example, I want to add this folder and it's content to the archive: 22610.1_amd64_en-us_professional_00fb7ba0_convert.
In the archive I get: C:\Users\userProfile\Downloads\22610.1_amd64_en-us_professional_00fb7ba0_convert. Any ideas how to make this relative path or trim it? Thank you.
You can use QDirIterator to recursively iterate over directory and subdirectories, and I believe you dont need to add nonempty directories at all, just files will be fine.
And why would you use stl container in qt, please use qt containers.
I want to download some files from my ftp server. The problem is, that only the last one has data, others 0 sized or it crashes when close QFile as a pointer.
My code:
QFtp *ftp = new QFtp(this);
ftp->connectToHost(FTP_HOST, FTP_PORT);
ftp->login(FTP_USERNAME, FTP_PASSWORD);
QFile *reportFile = nullptr;
connect(ftp, &QFtp::listInfo, [this](const QUrlInfo &ftpUrlInfo) {
if (ftpUrlInfo.isFile()) {
reportFile = new QFile("some local path" + ftpUrlInfo.name());
reportFile->open(QIODevice::WriteOnly);
ftp->get("some ftp path" + ftpUrlInfo.name(), reportFile, QFtp::Binary);
}
});
connect(ftp, &QFtp::done, [this]() {
qDebug() << "DONE!";
ftp->close();
ftp->deleteLater();
});
connect(ftp, &QFtp::commandFinished, [this]() {
qDebug() << "COMMAND FINISHED!";
if (reportFile != nullptr) {
reportFile.close();
reportFile->deleteLater();
}
});
ftp->list("ftp path to dir");
So, it should download the file, close it and deleteLater for all files in the ftp directory. Any ideas how to do it? Thanks.
I have finally fixed it!
My code:
QQueue<QFile*> reportQueue; //initialize the queue
connect(ftp, &QFtp::listInfo, [this](const QUrlInfo &ftpUrlInfo) {
if (ftpUrlInfo.isFile()) {
reportQueue.append(new QFile("local path" + "\\" + ftpUrlInfo.name()));
}
});
connect(ftp, &QFtp::done, [this]() {
emit reportsDataFinished();
});
connect(ftp, &QFtp::commandFinished, [this]() {
if (ftp->currentCommand() == QFtp::List) {
proceedDownload();
} else if (ftp->currentCommand() == QFtp::Get) {
reportFile->close();
reportFile->deleteLater();
proceedDownload();
}
});
if (ftp->error() == QFtp::NotConnected) {
emit ftpReportError(ftp->error());
} else {
ftp->list("ftp path to the dir");
}
void Test::proceedDownload()
{
if (!reportQueue.isEmpty()) {
reportFile = reportQueue.dequeue();
reportFile->open(QIODevice::WriteOnly);
QFileInfo ftpFileInfo(reportFile->fileName());
ftp->get("ftp path to file" + "/" + ftpFileInfo.fileName(), reportFile, QFtp::Binary);
}
}
I added the files to the QQueue, when ftp list command has been finished, I use function proceedDownload(). In the function, I dequeue() the queue to the reportFile and proceed with ftp get() function. When get ftp command finishes, I close and delete the file from memory, and again call the proceedDownload(). So the the whole process goes again until the queue is empty. I use emit reportsDataFinished(); signal in the connection to the slot closeFtp() where ftp closes and deleteLater() frees the resources. All files downloads well. Thank you.
this is my first question here, i always found the answers i need but today, that "always" has ended haha. My problem is that i'm trying to read a text file with QFile and QTextStream and save the values inside an STL vector. When i try to read the vector, I obtain that is empty(forgive any mistakes with my english, is no my first language). Here i leave you the methods.
bool TGraphic::process_data( void )
{
bool openingOk = false;
QString line;
if(QFile::exists( this->input_file.fileName() ))
{
openingOk = this->input_file.open(QIODevice::Text | QIODevice::ReadOnly);
QTextStream flujo(&input_file);
while(!(flujo.atEnd()))
{
line = flujo.readLine();
this->data.push_back( line.toInt() ); // data is std::vector<int> data;
}
}
return openingOk;
}
The compiler doesn't give me any errors but when i do this
void Ventana::on_pbGraphic_clicked()
{
imgGen = new TGraphic(fileName);
std::vector<int> aux(imgGen->getVector());
bool dataOk, graphicOk;
img = new QPixmap(400, 300);
dataOk = imgGen->process_data();
graphicOk = imgGen->process_graphic(*img);
if(dataOk && graphicOk && !(aux.empty())) // ** THE LAS CONDITION GAVE ME FALSE **
{
//ui->labGraphic->setPixmap(*img);
ui->labNombreArchivo->setText(QString::number(aux[0])); // I TRIED TO GET THE
} // THE FIRST VALUE OF
else // THE VECTOR AND THE
{ // PROGRAM FAILS THERE.
ui->labGraphic->setText("Error.");
}
}
in dialog.cpp i get a false. Can you guys help to see where is the problem? If you need extra information ask me. Thanks!
i have a problem with csv file reading. I'm pretty new to mfc and i hope someone can help me. So...i have a button and with it i open file dialog and choose csv file. In csv file i have diferent shapes(rectangle,ellipse,pollygon) with color and position info(separtor is ;). Now i need to show this informations in a ListBox and here i'm stuck. I got so far(code)...and i don't know it's ok and i can't find any good help so i hope someone can give me a hint.
void CDialogDrawing::OnBnClickedButton2()
{
TCHAR filtri[] = _T("CSV files (*.csv)|*.csv||");
CString path;
CFileDialog dlg(TRUE, _T("csv"), _T("*.csv"), OFN_FILEMUSTEXIST | OFN_HIDEREADONLY, filtri);
dlg.m_ofn.lpstrTitle = _T("Open...");
if(dlg.DoModal() == IDOK) //OK
{
path = dlg.GetPathName();
//
CStdioFile readFile;
CFileException fileException;
CString strLine;
if(readFile.Open(path, CFile::modeRead, &fileException))
{
while (readFile.ReadString(strLine));
{
seznamLikov.AddString(strLine);
}
}
else
{
CString strErrorMsg;
strErrorMsg.Format(_T("Can't open file %s , error : %u"), path, fileException.m_cause);
AfxMessageBox(strErrorMsg);
}
readFile.Close();
}
}
Trailing semi-colon after the while:
while (readFile.ReadString(strLine));
{
seznamLikov.AddString(strLine);
}
remove it as it is equivalent to:
while (readFile.ReadString(strLine)) {}
{
seznamLikov.AddString(strLine);
}
meaning AddString() will be invoked only once, after ReadString() fails.
I wrote the following code for retreiving data from a file(which already exists and permision is also given because i am on Windows OS), and creates items to display data fragments in a List, but the list won't show any thing. More over I figured out even when the file wasn't created, the FILE.EXISTS() function returned true. why is this so?
void MainWindow::on_listWidget_itemClicked(QListWidgetItem *item)
{
ui->listWidget_2->clear();
QListWidgetItem *itm=new QListWidgetItem;
ui->commentbutton->setEnabled(true);
QFile files("E:/"+QString::number(ui->listWidget->currentRow())+"com.txt");
if(files.exists())
{
if(!files.open(QFile::ReadOnly | QFile::Text))
{
QMessageBox::warning(this,"File Access!!!","The File containing data of the Items and Comments can't be acessed",QMessageBox::Ok);
return;
}
QTextStream in(&files);
QString data(in.readLine());
int x=0;
QString temp;
for(int i=0;;i++)
{
if(data.at(i)!='#' && data.at(i+1)!='#')
{
temp[x]=data.at(i);
x++;
}
else
if(data.at(i)=='#' && data.at(i+1)=='#')
{
x=0;
i++;
itm->setText(temp);
ui->listWidget_2->addItem(itm);
}
if(data.end())
break;
}
files.close();
}
the path at which the files are generated displays:
This is the data stored in 0com.txt file (comment file):
NewYork##London##
Thanks for your time!
1) 0com.txt actually exists. For what current row number in ui->listWidget do you have a "false" files.exists()?
2) data.end() returns a STL-style iterator, while your are incrementing by index. use
if(i>= data.size())
break;
3) Please show the content of "0com.txt" for further debugging