This is the last bit of the problem I have saving image to database and retrieving it. What I am trying to do now is to make it generic (before it was ico files and it worked) by using TWICImage. I am able to save and load it, but I get an exception while saving to the database.
Could not convert variant of type (Array Byte) into type (Integer)
If I click ok, everything is as usual. It is saved and loads and displays just fine. It must me something that I did wrong, but can't figure it out.
Here is the loading from file code snippet:
if (dlgOpenPictureFile->Execute())
{
TWICImage *Image = new TWICImage();
Image->LoadFromFile(dlgOpenPictureFile->FileName);
imgLogo->Picture = NULL;
imgLogo->Picture->Assign(Image);
if (dscMain->DataSet->State == dsBrowse)
{
dscMain->Edit();
}
TStream *StreamLogo = NULL;
try
{
StreamLogo = dscMain->DataSet->CreateBlobStream(dscMain->DataSet->FieldByName("Image"), bmWrite);
imgLogo->Picture->Graphic->SaveToStream(StreamLogo);
}
__finally
{
//at the time of delete it writes to the underlying buffer
delete StreamLogo;
delete Image;
}
}
dscMain is the datasource which we later post. The Image is of the type varbinary in the database.
Any insights to this problem is very much appreciated.
Edit:
After some testing, it looks like this is happening only for .png and .gif files.
IDE: Rad Studio Berlin
OS: Windows 10
Related
I'm very new to QT and I have an application which has a QTableWidget in it and I want to add save and load option to my application. the question is how to save and load data in QTableWidget. I found this page:http://doc.qt.io/qt-5/qtwidgets-tutorials-addressbook-part6-example.html#defining-the-addressbook-class but it wasn't useful:I tried a code like this to save:
void training::on_pushButton_3_clicked()
{
QVector<QTableWidgetItem*> outvector;
for(int i = 0;i<ui->tableWidget->rowCount();i++)
for(int ii=0;i<ui->tableWidget->columnCount();ii++)
outvector.append(ui->tableWidget->item(i,ii));
QString path = QFileDialog::getSaveFileName(this,QString("Save file path"),"",QString("table (*.tbl);;All Files (*)"));
if(path.isEmpty())
return;
else{
QFile file(path);
if(!file.open(QIODevice::WriteOnly)){
QMessageBox::information(this,"Error",file.errorString());
return;
}
else{
QDataStream out(&file);
out.setVersion(QDataStream::Qt_5_11);
out<<outvector;
}
}
}
Is this right?! If it works how to load the information again; if not how to save and load data in tablewidget?
Any help would be appreciated.
Make this correction to your code:
...
for(int ii=0;ii<ui->tableWidget->columnCount();ii++)
...
For this (save and load data in QTableWidget) look at Serialization with Qt, So you need to consider what exactly you want to Save/load (serialize). since QVector is serializable, I think your code won't complain, but indeed it won't store your actual data, QTableWidgetItems, because that data type is not in list of serializable types - try to directly save an individual item and you will know what errors will come. Moreover, serializing compound types (vector of table items) may not be the right approach even if both types are supported.
In order to solve your issue, you need to serialize whatever data you store in your QTableWidget items, for example read text from item and store ...etc.
Thanks it's fixed up using
item.write(outstream);
I saved everyitem using write function then with same order I used read function item.read(instream) to load it again.
I am currently writing an application in Qt, which is basically a warehouse. An application reads CSV, enables user to process it and enables to show picture of each good. I tried displaying picture using QLabel and Pixmap, however nothing happens even though the file is in the same folder and the name provided is exactly as it should be. Is it the resources issue or my code fails somehow? Is there any possibility to display the image without adding it to resources in order to avoid adding many photos manually?
void ImageViewer::viewImage(QString imgName)
{
QString pathWithName = imgName;
pathWithName.append(".jpg");
ui->label->setPixmap( QPixmap(pathWithName) );
ui->label->show();
update();
}
Sorry for any mistakes in post creation or code displaying here- it's my first post.
Edit:
I am adding code from MainWindow (called CsvReader in my project) to how I'm invoking the method viewImage:
void CsvReader::on_imgView_clicked()
{
ImageViewer* img = new ImageViewer(this);
img->setModal(true);
img->exec();
QModelIndex List selInd ui->tableView->selectionModel()->selectedIndexes();
QString id = model->item(selInd.first().row(), 0)->text();
img->viewImage(id);
}
Edit 2:
Solved. Had to change path using QDir:
QDir* directory = new QDir("/home/kokos/Magazyn/photos");
QFileInfo checkFile(*directory, pathWithName);
Thanks in advance,
Kokos
Confirm your file's location and existence first. Add this;
QFileInfo checkFile(pathWithName);
if (checkFile.exists() && checkFile.isFile()) {
// your code
}
I am working in an application where there is a conbobox and a picturebox. The user selects a path and the conbobox loads paths to 2000 images, and displays the first one. When the user changes the index of the conbobox the image displayed changes, but I don't know how to delete the image in the picturebox.
If I just overwrite the image it doesnt do the job, as when I do it repeatedly the program crashes because of memory. How do I delete a image Inside the picturebox?
EDIT:
I made few changes and can't seem to reproduce the error again.. so maybe it was something else. but just for checking, is this code leaking memory?
tips: config is a singleton containing where some info, in this case, where the images are.
private: System::Void comboBox_image1_SelectedIndexChanged(System::Object^ sender, System::EventArgs^ e) {
System::String^ aux;
DIC_config* config=DIC_config::Instance();
if(config->images_path!=NULL){
aux=gcnew System::String(config->images_path);
aux=aux+"\\CAM_0\\Snap_0_0"+(this->comboBox_image1->SelectedIndex+1)+".bmp";
System::IO::FileStream^ image_file=gcnew System::IO::FileStream(aux,System::IO::FileMode::Open,System::IO::FileAccess::Read);
System::Drawing::Bitmap^ img = gcnew System::Drawing::Bitmap(image_file);
this->pictureBox_image1->Image=img;
//img->~Bitmap(); this doesnt work, deletes the image of picturebox and makes the program chrash
}
}
You have to dispose the old image. Forgetting to do so makes it likely your program runs out of unmanaged memory when the garbage collector doesn't run frequently enough. Bitmap objects are quite small, you can allocate thousands of them without ever triggering a GC, but can consume a lot of unmanaged memory for the pixel data. You dispose objects in C++/CLI with the delete operator, it calls IDisposable::Dispose().
Do note that the FileStream you use is also a disposable object. Doing it this way requires you to keep the stream opened while the bitmap is in use and close it afterwards. You correctly did not dispose the stream but forgot closing it. Too hard to get right, it is much easier to use the Bitmap constructor that accepts a string for the file path so the Bitmap class manages the underlying stream itself. Fix:
aux = config->images_path;
aux += ....;
System::Drawing::Bitmap^ img = gcnew System::Drawing::Bitmap(aux);
delete this->pictureBox_image1->Image;
this->pictureBox_image1->Image = img;
This doesn't work because you are trying to call destructor of the class, not the instance. Furthermore you do not need to call it as System::Drawing::Bitmap is under control of garbage collector, so the finalizer ( !Bitmap() ) will be called automatically if it's not referenced any longer.
What you can do if you want to close it in picturebox is
delete this->pictureBox_image1->Image;
image_file->Close(); //after closing/deleting the open bitmap
btw. your code is not pure c++, but c++/cli, so I've added the tag
First set a null pointer to the Image property and refresh the pictureBox, as given below,
pictureBox_image1->Image = nullptr;
pictureBox_image1->Refresh();
Language: C++
Development Environment: Microsoft Visual C++
Libraries Used: MFC
Background: So I've created an application that is basically a large preference dialog where the user can configure a number of pages, each with a bunch of different settings. When the user is finished, he/she has three options for saving the preferences (as XML): Save Current [page], Save These, and Save All.
I'm working with the Save These function right now. When the user chooses this option, a dialog appears with check boxes for each page, allowing them to choose which pages they wish to output. Once they choose the directory into which they wish the files to be saved, the magic happens and the XML files are written.
Problem: I have a function (UpdatePageData) that will detect which page is being displayed and update the current page's data by calling UpdateData. I have put in a break point to watch to make sure the variables are being filled with the user's inputted values, and everything is dandy and working correctly. However, when the program jumps from the checkbox dialog (where I call UpdatePageData) to the classes for the pages I'm saving, suddenly all of the values are wrong.
Below I've included some code that will help you guys understand the program flow.
NOTE: In SaveThese, I am currently just working on saving a single page...I will have it update all pages selected once I figure out the problem I'm having.
Location: Main Dialog
void CSAPrefsDialog::OnSaveThese()
{
int msgboxID = ::MessageBox(
NULL,
(LPCSTR)"Are you sure you want to save?",
(LPCSTR)"Save These",
MB_ICONQUESTION | MB_OKCANCEL
);
switch (msgboxID)
{
case IDCANCEL:
break;
case IDOK:
UpdatePageData();
CSaveThese m_sT;
m_sT.DoModal();
break;
}
}
Location: Main Dialog
void CSAPrefsDialog::UpdatePageData()
{
if ((m_iCurPage >= 0) && (m_iCurPage < m_pages.GetSize()))
{
pageStruct *pPS = (pageStruct *)m_pages.GetAt(m_iCurPage);
if (pPS)
{
ASSERT(pPS->pDlg);
if (pPS->pDlg)
{
if (!pPS->pDlg->UpdateData()) // THIS WORKS. THE DATA IS UPDATED.
{
AfxMessageBox("Did not update data.");
}
}
}
}
}
Location: SaveThese Class
void CSaveThese::OnBnClickedOk()
{
// TODO: Add your control notification handler code here
UpdateData(TRUE); // figures out which boxes are checked for saving
CDirDialog dir;
CSAPrefsDialog prefsDialog;
if(dir.DoBrowse())
{
prefsDialog.m_strDirectorySavePath = dir.m_strPath;
}
// [ other if-statements like the one below to check the check boxes ]
}
if(m_bST_FS)
{
FSC_Main m_FS;
m_FS.Save(prefsDialog.m_strDirectorySavePath);
}
OnOK();
}
Location: FSC_Main Class
void FSC_Main::Save(CString dirPath)
{
if(Validate())
{
dirPath += "\\FS_Config.xml";
FILE *fp = fopen(dirPath, "w+");
WriteXML(fp);
fclose(fp);
}
}
By the time it gets to WriteXML, the values have either reverted back to their initialized values (empty strings and -1 for all combo boxes), or have strange values (empty for strings, and large numbers for combo boxes).
I imagine I just have something in the wrong place. I'm just not sure why this is happening, and it's really the biggest hurdle between me and really getting this project rolling.
Jon, Very hard to understand your code. What i understood is you have a member variable m_pages in CSAPrefsDialog dialog class which you are updating by calling UpdateData. And then you are creating a local variable CSaveThese m_sT and calling DoModal. Do you expect CSaveThese class should hold the values of m_Pages?
I am trying to convert a RTF document to PDF. I have this code:
// TestCOMPDF.cpp : Defines the entry point for the console application.
//
#include <windows.h>
#include <tchar.h>
#include <objbase.h>
#include <atlbase.h>
#import "MSVBVM60.DLL" rename ( "EOF", "VBEOF" ), rename ( "RGB", "VBRGB" ) //if you don't use this you will be in BIG trouble
#import "PDFCreator.exe"
int _tmain(int argc, _TCHAR* argv[])
{
CoInitialize(NULL);
{
CComPtr<PDFCreator::_clsPDFCreator> pdfObject;
HRESULT hr = pdfObject.CoCreateInstance(L"PDFCreator.clsPDFCreator");
pdfObject->cStart("/NoProcessingAtStartup", 1);
PDFCreator::_clsPDFCreatorOptionsPtr opt = pdfObject->GetcOptions();
opt->UseAutosave = 1;
opt->UseAutosaveDirectory = 1;
opt->AutosaveDirectory = "c:\\temp\\";
opt->AutosaveFormat = 0; // for PDF
opt->AutosaveFilename = "gigi13";
pdfObject->PutRefcOptions(opt);
pdfObject->cClearCache();
_bstr_t DefaultPrinter = pdfObject->cDefaultPrinter;
pdfObject->cDefaultPrinter = "PDFCreator";
hr = pdfObject->cPrintFile("c:\\temp\\RTF\\garage.rtf");
pdfObject->cPrinterStop = false;
while(true)
{
printf("sleep\n");
Sleep(1000);
if(pdfObject->cCountOfPrintjobs == 0)
break;
}
printf("done\n");
pdfObject->cPrinterStop = true;
pdfObject->cDefaultPrinter = DefaultPrinter;
}
CoUninitialize();
return 0;
}
When running this code sample instead of creating directly the PDF it prompts me with a Save dialog offering me the option to the output only with the option of choosing a TIFF file (which is not wanted). Can someone point me into the right direction or offer some suggestions?
Thanks,
Iulian
This is only a guess... I had a similar problem -- not when using PDFCreator programmatically (this is beyond my capabilities), but when using it as my standard printer to print to PDFs.
First I used it for a couple of days without any problem. Not I had installed it, but my partner. As I said... it just worked, and created beautiful PDFs.
Then, somehow, someone on our home computer (we are 3 different persons using it) must have changed the setting (maybe inadvertedly) to make it output TIFF instead of PDFs. For me, my default printer was named "PDFcreator" and it confused the hell out of me why it suddenly wanted to create TIFFs.
Meanwhile I've poked a lot in the user interface of all its settings, and learned to know where to look if something goes wrong.
The newest version in its lefthand treeview panel lists an item named "Save". If you select it, you can configure default filename conventions as well as "Standard save format". In my case in the dropdown listview there was "TIFF" selected instead of "PDF".
Looking at your code, you are somehow calling PDFCreator.exe (I don't understand the details, but I can see this string in your code). My bet would go towards this: somehow, the user account which your code uses to run under has his Standard save format set to TIFF. It may be that you look at the printer settings (on my Windows XP, I just type control printers, and rightclick the PDFCreator printername to select Properties...) and find nothing suspicious.
However, PDFcreator stores its settings for each user into a different location, probably in %userprofile%\local settings\temp\pdfcreator\..., or even in the registry...