QFile isn't opening - c++

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

Related

QListWidget deleting QListWidgetItem causes segmentaion fault

I have a C++ application where I am reading pcap file format and processing usb packets. For each packet, I would like to create a QListWidgetItem to which I am storing some data and then adding it to the QListWidget. Here is where the trouble begins. According to QListWidget documentation, after inserting item :
The list widget will take ownership of the item.
So what I thought is that its on QListWidget to delete all QListWidgetItems. The items are added fine, but when I close my app(I suppose thats when desctructor od QListWidget is called so he is calling desctructor of each QListWidgetItem) I get delete_scalar exception. According to call stack, deletion of some QListWidgetItem triggers it :
Snippet of my code (this function is being called for each packet in pcap file and is responsible for creating and adding items):
void ItemManager::ProcessPacket(QByteArray packetData)
{
const unsigned char* packet = (unsigned char*)packetData.data();
PUSBPCAP_BUFFER_PACKET_HEADER usbh = (PUSBPCAP_BUFFER_PACKET_HEADER)packet;
QListWidgetItem* item = new QListWidgetItem;
//set USBPCAP header to item
QByteArray usbhArray((const char*)packet, sizeof(USBPCAP_BUFFER_PACKET_HEADER));
item->setData(dataHolder->USBPCAP_HEADER_DATA, QVariant(usbhArray));
packet += sizeof(USBPCAP_BUFFER_PACKET_HEADER);
if (usbh->transfer == USBPCAP_TRANSFER_ISOCHRONOUS || usbh->transfer == USBPCAP_TRANSFER_CONTROL) //check for optional header data
{
int additionalDataSize = usbh->headerLen - sizeof(USBPCAP_BUFFER_PACKET_HEADER);
if (additionalDataSize > 0)
{
//set additional header data to item
QByteArray additionalDataArray((const char*)(packet), additionalDataSize);
item->setData(dataHolder->TRANSFER_OPTIONAL_HEADER, QVariant(additionalDataArray));
packet += additionalDataSize;
}
else
{
item->setData(dataHolder->TRANSFER_OPTIONAL_HEADER, QVariant()); //QVariant creates invalid QVariant, later i just need to check with QVariant::isValid()
}
}
else
{
item->setData(dataHolder->TRANSFER_OPTIONAL_HEADER, QVariant());
}
//set leftover data to item
QByteArray leftoverDataArray((const char*)packet, usbh->dataLength);
item->setData(dataHolder->TRANSFER_LEFTOVER_DATA, QVariant(leftoverDataArray));
listWidget->insertItem(listWidget->count(), item);
}
Calling of ProcessPacket function :
void ItemManager::ProcessFile(QString filename, bool liveReading)
{
if (fileReader.OpenNewFile(filename))
{
if (fileReader.ReadFileHeader())
{
while (!stopButtonClicked)
{
while (!fileReader.EndOfFile())
{
QByteArray packetData = fileReader.GetPacket();
if (!pauseButtonClicked)
{
ProcessPacket(packetData);
}
}
parent->Refresh(); //this is just calling QCoreApplication::processEvents();
if (!atBottomOfList)
{
listWidget->scrollToBottom();
}
if (liveReading)
{
Sleep(50);
}
else
{
return;
}
}
}
}
}
EDIT
I found out that this problem is happening only when appending to QListWidget through ItemManager class. In my main Q_OBJECT class USB_Packet_Analyzer(which holds QlistWidget that I am appending to) i have slot on_OpenButton_clicked() which looks like this :
void USB_Packet_Analyzer::on_OpenButton_clicked()
{
QString fil = QFileDialog::getOpenFileName(this, "Select source file", ".", "Pcap files (*.pcap)");
ItemManager manager(ui.listWidget,this);
manager.ProcessFile(fil, ui.liveCaptureRadioButton->isChecked());
}
where in ItemManager class constructor looks like this :
ItemManager::ItemManager(QListWidget* listWidget, USB_Packet_Analyzer* parent)
{
this->stopButtonClicked = false;
this->pauseButtonClicked = false;
this->atBottomOfList = false;
this->listWidget = listWidget;
this->parent = parent;
this->dataHolder = DataHolder::GetDataHolder();
}
Now, if I add items in on_OpenButton_clicked() slot and close the app, everything is fine. But when I create ItemManager instance and append items in that class, the error occurs. Could it be that I am not allowed to pass QListWidget* as parameter ?
You have to create a new item inside your loop. You must not reuse the pointer because no content is copied, only the pointer is stored within the QListWidget
To this day I am not completely sure what caused the error, but it was fixed after I modified USBPCAP structs which I were using. They use all kind of stuff like #pragma pack(1) , #pragma pack(push) and so on. It looks like I was missing some of those, which might result in some undefined behaviour while using them.

how to get single string from qstringlist

I am building an image viewer application. I store all image path into qSringlist. Now I need to get one image path every time. How can i do this ?
Here is my code
void MainWindow::on_btn_Next_clicked()
{
//initial value
int count = 0;
do {
//show image into label
QImage img(fileName.at(count));
ui->lbl_Image->setPixmap(QPixmap::fromImage(img));
qDebug() << fileName.at(count);
count++;
return;
} while (count < fileName.size());
}
initialize count outside your on_btn_Next_clicked() method and then every time the method is called increment the counter, when the counter is the same size of the QStringList reset it back to 0
// initialize count outside the method
int count = 0;
void MainWindow::on_btn_Next_clicked()
{
if(count <= filename.size()) {
//show image into label
QImage img(fileName.at(count));
ui->lbl_Image->setPixmap(QPixmap::fromImage(img));
qDebug() << fileName.at(count);
this->count++;
return;
} else {
//reset the counter back to 0
this->count = 0;
}
}
First get the filename:
const QStringList fileNames = QFileDialog::getOpenFileNames(this, tr("Open File"), QDir::currentPath());
Use a foreach loop to iterate:
foreach(const QString& image, fileNames){
ui->lbl_Image->setPixmap(QPixmap::fromImage(QImage(image)));
qDebug() << "Get this filename: " << image;
}
All previous answers are correct on how to get a specific item from the list, even the question's code does that correctly.
However all fail to mention that this will always show the last image in the list, since the UI never gets a chance to display any of the others.
The loop is never returning to the event loop, thus never allowing the application to process the label's update() request.

Open function in Qt

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

Cant read text file and save it in stl vector with QFile

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!

Copying a (rtf) table into the clipboard via QT (or: Writing a QTextDocument into clipboard)

I need my QT application to create a table and copy this table into the clipboard, so that it can be pasted as table into libreoffice Writer or MS Word later.
My first approach was to create html code for the table and insert it into the clipboard with
QClipboard *clipboard = QApplication::clipboard();
QMimeData *mimeData = new QMimeData();
mimeData->setData("text/html", html.toUtf8());
clipboard->setMimeData(mimeData, QClipboard::Clipboard);
This approach didn't work. When pasting, the table cells where just appended to each other and inserted without formatting.
My second approach using RTF:
QTextDocument rtfDocument;
rtfDocument.setHtml(html);
But I found no way to copy this QTextDocument into the clipboard. Is there any?
If I could get the RTF code out of the QTextDocument, I could use a way like
QClipboard *clipboard = QApplication::clipboard();
QMimeData *mimeData = new QMimeData();
mimeData->setData("text/rtf", rtfDocument.getCode());
clipboard->setMimeData(mimeData, QClipboard::Clipboard);
But I also didn't find a function returning the rtf code.
edit:
With the last code box above I have a working way to copy rtf code into the clipboard. So any solution that can create RTF code representing a table would solve my problem.
I'm not sure what the source of your data is, but here is code we used to subclass the normal QTableView to make it copy-able. Some of the code has been cut out, but you can get the basic idea. RTF/HTML is overkill--all the spreadsheets accept good ol' CSV.
Of course, this answer won't help at all if you require formatting. I wasn't clear from your question if that was a requirement or not.
// Escapes a string according to RFC-4180 specification.
static QString csvEscape(const QString &value) {
if (value.contains(QRegExp(QLatin1String("[\"\\n\\r,]")))) {
QString escaped(value);
escaped.replace(QLatin1String("\""), QLatin1String("\"\""));
return QString::fromLatin1("\"%1\"").arg(escaped);
} else {
return value;
}
}
void ClipboardAwareTableView::Copy() const {
QModelIndexList indexes = selectedIndexes();
Q_ASSERT(!indexes.isEmpty());
if(indexes.isEmpty()) {
return;
}
// The default sort is by rows then columns. This is what we want.
qSort(indexes);
// Remember the mapping between model columns and visible columns. This is
// local instead of an instance member because it would need to be invalidated
// any time a column is added, removed, or moved. The minor performance hit
// is worth the simplicity.
QHash<int, int> map_cache;
// Before we start exporting text, we have to know the index of the left-
// most column in our selection range so we can add the appropriate number
// of column separators.
int minimum_column = GetViewColumnIndex(indexes.first().column(), &map_cache);
for (int i = 1; i < indexes.size(); ++i) {
minimum_column =
qMin(minimum_column,
GetViewColumnIndex(indexes.at(i).column(), &map_cache));
}
// Keep track of the previous index so that we know if we need a new line and
// how many column separators to insert. We start with an invalid index.
QModelIndex previous;
QString text;
for (int i = 0; i < indexes.size(); ++i) {
QModelIndex current = indexes.at(i);
// Do we need to add a new line character?
if (previous.isValid() && current.row() != previous.row()) {
text.append(QLatin1String("\n"));
}
// Are we on a new line?
if (!previous.isValid() || current.row() != previous.row()) {
// Add enough separators to get from the minimum to the current column.
text.append(QString::fromLatin1(",")
.repeated(GetViewColumnIndex(current.column(), &map_cache) -
minimum_column));
} else {
// Add enough separators to get from the previous to the current column.
text.append(QString::fromLatin1(",")
.repeated(GetViewColumnIndex(current.column(), &map_cache) -
GetViewColumnIndex(previous.column(), &map_cache)));
}
// Append the text. If the column delegate is a QStyledItemDelegate, we use
// the display text.
QStyledItemDelegate *delegate =
qobject_cast<QStyledItemDelegate*>(
itemDelegateForColumn(current.column()));
if (delegate) {
text.append(csvEscape(delegate->displayText(current.data(), QLocale())));
} else {
text.append(csvEscape(current.data().toString()));
}
previous = current;
}
qApp->clipboard()->setText(text);
}
int ClipboardAwareTableView::GetViewColumnIndex(
int model_column_index,
QHash<int, int> *cached_mappings) const {
if (cached_mappings->contains(model_column_index)) {
return cached_mappings->value(model_column_index);
}
int view_index = 0;
for (int i = 0; i < model()->columnCount(); ++i) {
if (model_column_index == i) {
cached_mappings->insert(model_column_index, view_index);
return view_index;
} else if (!isColumnHidden(i)) {
++view_index;
}
}
throw std::invalid_argument("model_column_index was out of range.");
}
void ClipboardAwareTableView::keyPressEvent(QKeyEvent *event) {
if (event->matches(QKeySequence::Copy) && !selectedIndexes().isEmpty()) {
Copy();
event->accept();
return; // The base class implementation will overwrite the clipboard.
}
event->ignore();
QTableView::keyPressEvent(event);
}
You could try using QTextDocument::toHtml() and set the mime type to text/html
I wrote in gedit 1[tab space]2[tab space]3\n4[tab space]5[tab space]6 and copied it to spreadsheet and it worked. So, I think if you use "\t" for separating cells in rows and "\n" for separating rows, it will work.