I have a file with hundreds and hundreds of pictures (photographs) that I need to show in preview to some people. This preview should be a purchase order (rapidly, nothing "pro") and I would give them so that the people can put a cross in the case they want a picture and which size (as simple as that).
I tried to auto-generate the purchase order, there would be two per page (A4) on a PDF.
I use Qt/C++ and three objects :
QPdfWriter
QPainter
QImage
Here's the beginning of the pdf-generation class :
int order = 1;
qDebug() << "pdf creation";
QString logoName = QFileDialog::getOpenFileName(0, "Sélectionner le logo", QString(), "Images (*.png *.bmp *.jpg)");
QString fileName = QFileDialog::getSaveFileName(0, "Export PDF",
QString(), "*.pdf");
QString dir = QFileDialog::getExistingDirectory(0, "Sélectionner le dossier de photos");
QFont titleFont("Arial", 24);
titleFont.setUnderline(true);
QFont textFont("Times new roman", 12);
QDirIterator it(dir);
if (!fileName.isEmpty()) {
if (QFileInfo(fileName).suffix().isEmpty())
fileName.append(".pdf");
QPdfWriter writer(fileName);
QPainter painter(&writer);
painter.setRenderHint(QPainter::Antialiasing);
int height = painter.device()->height();
int semi = height/2;
int width = painter.device()->width();
int digits = 1;
qDebug() << "height : " << height << " width : " << width;
QImage logo(logoName);
QImage finalLogo = logo.scaled(3750, 1250, Qt::KeepAspectRatio);
while(it.hasNext()){
it.next();
digits = countDigits(order);
if(it.fileInfo().isFile()){
if(order%2!=0){
painter.drawImage(300,100,finalLogo);
QImage currentPreview(it.filePath());
QImage finalPreview = currentPreview.scaled(3250,4000, Qt::KeepAspectRatio);
painter.drawImage(650,1500,finalPreview);
The rest is just the drawing of the text/borders.
I tried it in debug : works fine
I compiled in release, put all the .dll in the file (including platform) and ran it without Qt : works fine
Then I put the files on a usb stick, I put it on the other computer that I use for the pictures, that computer does NOT have Qt.
I launched the .exe and the app showed exactly as on my dev-pc
But when I called the PDF creation I filled the FileDialogs with my data, it runs for around 30 secs (a lot of pictures in the file) and generates the PDF.
I opened it and ... not a single picture on the PDF.
All the lines and texts are in place without any problem, it generates the right amount of purchase order but not a single picture on it ... Neither the logo (QImage finalLogo) nor the preview (QImage finalPreview).
It's like QPainter::drawText()/drawLine() does work, but not QPainter::drawImage.
It's disturbing since it works on a computer but not on another ... Did I do something wrong when compiling/releasing ?
(Answered in the comments - converted to a community wiki.)
The OP wrote:
Ok ! I figured it out. The dll to handle the jpeg was not in the right directory, I moved it to the right one and it worked.
Related
So I have the tutorial project Notepad. I am trying to use QSettings so that it saves the font,font size and other font related options in a file but it never loads them properly and when I check the config file, the values look quite weird.
void Notepad::saveSettings()
{
QSettings setting("MyTE","myte");
QFont font = this->font();
setting.beginGroup("MainWindow");
setting.setValue("text.font",font.toString());
setting.setValue("text.font.family",font.family());
setting.setValue("text.font.size",font.pointSize());
setting.setValue("text.font.bold",font.bold());
setting.setValue("text.font.italic",font.italic());
setting.endGroup();
qDebug() << "Saved";
}
void Notepad::loadSettings(){
QSettings setting ("MyTE","myte");
QFont font = setting.value("text.font",QString()).toString();
setting.beginGroup("MainWindow");
QString fontFamily = setting.value("text.font.family",QString()).toString();
int fontSize = setting.value("text.font.size",12).toInt();
setting.setValue("text.font.size",fontSize);
//bool fontIsBold = setting.value("text.font.bold",false).toBool();
//bool fontIsItalic = setting.value("text.font.italic",false).toBool();
setFont(font);
font.setPointSize(fontSize);
setting.endGroup();
qDebug() << "Loaded";
}
I uncommented the bold ones because they simply don't work.
I have 2 buttons that correspond to these 2 functions and I also call loadSettings() when the app first starts.
Here is the output in the config file, that never changes and just resets to these weird values.
[MainWindow]
text.font=",9,-1,5,50,0,0,0,0,0"
text.font.bold=false
text.font.family=
text.font.italic=false
text.font.size=9
I am trying to build a command log on a user interface. Meaning, when the user click a button, check a box, upload some images etc, basically every time the user interacts with the user interface the action is recorded inside a QListWidget Command Log shown below. Basically this is how the ui looks as soon as the user run it:
And this is what I am try to achieve everytime the user interacts with the ui:
Below snippets of code from the constructor:
mainwindow.h
private:
QListWidget *mNewTextSQLLog;
mainwindow.cpp
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
mDockWidget_A = new QDockWidget(QLatin1String("Command Log"));
mDockWidget_A->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);
mDockWidget_A->setMinimumHeight(30);
// Adding object to the DockWidget
mNewText = new QListWidget;
mNewText->setStyleSheet("background-color: light grey;");
mNewText->setMinimumHeight(50);
mNewText->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
mDockWidget_A->setWidget(mNewText);
addDockWidget(Qt::BottomDockWidgetArea, mDockWidget_A);
resizeDocks({mDockWidget_A}, {200}, Qt::Horizontal);
}
And then some command of the ui, for example here is when the user upload images using a QPushButton and images are also shown on a QLabel:
void MainWindow::imageOriginlUploadB()
{
dir_Original_B = QFileDialog::getExistingDirectory(this, tr("Choose an image directory to load"),
filesListRight, QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
if(dir_Original_B.length() > 0){
QImage image;
QDir dirBObj(dir_Original_B);
QStringList filesListRight = dirBObj.entryList(QDir::NoDotAndDotDot | QDir::System | QDir::Hidden | QDir::AllDirs | QDir::Files, QDir::DirsFirst);
ui->labelOrigImageB->setPixmap(QPixmap::fromImage(image.scaled(125,125,Qt::KeepAspectRatio,Qt::SmoothTransformation)));
for ( int i = 0 ; i < filesListRight.size() ; i++ )
{
ui->listWidgetOriginalImgB->addItem(filesListRight.at(i));
}
ui->listWidgetOriginalImgB->update();
ui->labelOrigImageB->show();
}
}
void MainWindow::on_originalmgB_clicked()
{
imageOriginlUploadB();
}
or here is resizing the QGraphicsView using a QPushButton:
void MainWindow::on_fitViewBtn_clicked()
{
ui->graphicsViewLX->fitInView(mLeftScene->sceneRect(), Qt::KeepAspectRatio);
ui->graphicsViewRX->fitInView(mRightScene->sceneRect(), Qt::KeepAspectRatio);
}
And this is the activation of a QCheckBox:
void MainWindow::on_checkBoxScreen_A_toggled(bool checked)
{
if(ui->checkBoxScreen_A->isEnabled()) {
if(checked)
{
ui->checkBoxScreen_A->setText("Active");
ui->saveToFile_A->setEnabled(true);
ui->saveToFile_A->setStyleSheet("QPushButton{ background-color: green }");
}
else {
ui->checkBoxScreen_A->setText("Inactive");
ui->saveToFile_A->setEnabled(false);
ui->saveToFile_A->setStyleSheet("QPushButton{ background-color: grey }");
}
}
}
How to achieve that?
Thank you very much for pointing in the right direction
I think QListWidget isn't quite the right widget to use for a Command Log -- you probably want to use either a QPlainTextEdit or a QTextEdit instead. (The main difference between the two is that QPlainTextEdit is optimized for displaying large amounts of text, at the expense of not supporting some of the fancier text-formatting features provided by QTextEdit)
Once you've created one of those two widgets, adding text to the bottom of log is just a matter of calling appendPlainText() (or append()) on the widget each time you want to add another line of log-text.
Unless you want to allow the user to edit the text in the Command Log, calling setReadOnly(true) on the widget is also a good idea.
(If you also want the log-view to automatically scroll to the bottom so that the newly-added text will be visible, you can also call myCommandLogWidget->verticalScrollBar()->setValue(myCommandLogWidget->verticalScrollBar()->maximum()); after adding the text)
I need your help! Im currently really new to wxWidgets as a uni student. I am trying to load a .gif file using wxWidgets. I tried using the code below... but it only loads 1 frame, it doesn't move/ change to the other frames, it's basically a still picture. The file is .gif extension, and it has 3 frames or so. The location of the image is already correct. Help would be much appreciated!
Thank you
#include "ImageWindow.h"
#include <wx/stdpaths.h>
#include <wx/filename.h>
BEGIN_EVENT_TABLE(ImageWindow, wxWindow)
EVT_PAINT(ImageWindow::OnPaint)
END_EVENT_TABLE()
ImageWindow::ImageWindow(wxFrame *parent)
: wxWindow(parent, wxID_ANY)
{
this->SetBackgroundColour(wxColour(*wxWHITE));
wxImageHandler *gifLoader = new wxGIFHandler();
wxImage::AddHandler(gifLoader);
this->LoadPotatoBitmap();
}
ImageWindow::~ImageWindow()
{
delete potatoBitmap;
}
void ImageWindow::LoadPotatoBitmap()
{
wxStandardPaths &stdPaths = wxStandardPaths::Get();
wxString fileLocation = stdPaths.GetExecutablePath();
wxImage image(wxT("A:\\Projects\\TestGif\\Assets\\Kuning.gif"),
wxBITMAP_TYPE_GIF);
potatoBitmap = new wxBitmap(image);
}
void ImageWindow::OnPaint(wxPaintEvent &event)
{
wxPaintDC pdc(this);
if (potatoBitmap != nullptr)
{
pdc.DrawBitmap(*potatoBitmap, wxPoint(150, 100), true);
}
}
You are not specifying the index of the image in the constructor and that's why you see the default one as you can see in the wxWdigets documentation:
wxImage::wxImage ( const wxString & name,
wxBitmapType type = wxBITMAP_TYPE_ANY,
int index = -1
)
index Index of the image to load in the case that the image file contains multiple images. This is only used by GIF, ICO and TIFF handlers. The default value (-1) means "choose the default image" and is interpreted as the first image (index=0) by the GIF and TIFF handler and as the largest and most colourful one by the ICO handler.
But, you should also consider wxAnimationCtrl (see this sample)
Use wxAnimationCtrl for playing gif animations
or
Use extract each frame from the gif image and draw one by one using wxTimer.
So I'm trying to choose random image from file system of my pc and make it background in wiget. So thats why I'm opening QFileDialog and using it. qDebug gives me right path to the image, but still it doesn't work.
void ChatWindow::on_actionImage_triggered()
{
QString fileName = QFileDialog::getOpenFileName(
this, tr("Open file"), "/home", tr("Images(*.jpg)")
);
QString filePath(fileName);
qDebug () << filePath;
setStyleSheet(
"ChatWindow{border-image:url(:" +
filePath +
") 0 0 0 0 stretch stretch;}"
);
QGraphicsOpacityEffect * effect1 =
new QGraphicsOpacityEffect(ui->messageHistory);
effect1->setOpacity(0.8);
ui->messageHistory->setGraphicsEffect(effect1);
ui->messageHistory->setStyleSheet("background-color: white;");
QGraphicsOpacityEffect * effect2 =
new QGraphicsOpacityEffect(ui->roomTree);
effect2->setOpacity(0.8);
ui->roomTree->setGraphicsEffect(effect2);
ui->roomTree->setStyleSheet("background-color: white;");
QGraphicsOpacityEffect * effect3 =
new QGraphicsOpacityEffect(ui->messageInput);
effect3->setOpacity(0.8);
ui->messageInput->setGraphicsEffect(effect3);
ui->sendButton->setStyleSheet("background-color: none;");
}
I've seen this one Unable to set the background image in Qt Stylesheet related to my problem, but in my case it doesn't work.
According to the documentation, there is no such property called border-image: what you're searching for is background-image.
Moreover, since you're also specifying other background's parameters, you should use background.
Moreover, since your file is on the disk and not in the resources, the url should not start with :: type url(" + filePath + ") instead of url(:" + filePath + ").
The corrected syntax:
setStyleSheet(
"ChatWindow{background:url(" +
filePath +
") 0 0 0 0 stretch stretch;}"
);
I have a problem: my project is a very simple one with a QTextEdit and a QSyntaxHighlighter, I'm trying to load a .cpp file and highlighting just the eighth line of that file, but the QTextEdit can't load the entire file if I ask it to highlight the line.
The following image shows the problem:
The relevant code of the application is the following:
void MainWindow::openFile(const QString &path)
{
QString fileName = path;
if (fileName.isNull())
fileName = QFileDialog::getOpenFileName(this,
tr("Open File"), "", "C++ Files (*.cpp *.h)");
if (!fileName.isEmpty()) {
QFile file(fileName);
if (file.open(QFile::ReadOnly | QFile::Text))
editor->setPlainText(file.readAll());
QVector<quint32> test;
test.append(8); // I want the eighth line to be highlighted
editor->highlightLines(test);
}
}
and
#include "texteditwidget.h"
TextEditWidget::TextEditWidget(QWidget *parent) :
QTextEdit(parent)
{
setAcceptRichText(false);
setLineWrapMode(QTextEdit::NoWrap);
}
// Called to highlight lines of code
void TextEditWidget::highlightLines(QVector<quint32> linesNumbers)
{
// Highlight just the first element
this->setFocus();
QTextCursor cursor = this->textCursor();
cursor.setPosition(0);
cursor.movePosition(QTextCursor::Down, QTextCursor::MoveAnchor, linesNumbers[0]);
this->setTextCursor(cursor);
QTextBlock block = document()->findBlockByNumber(linesNumbers[0]);
QTextBlockFormat blkfmt = block.blockFormat();
// Select it
blkfmt.setBackground(Qt::yellow);
this->textCursor().mergeBlockFormat(blkfmt);
}
However if you want to test the project with the cpp file I used (in the directory FileToOpen\diagramwidget.cpp), here's the complete source
http://idsg01.altervista.org/QTextEditProblem.zip
I've been trying to solve this for a lot of time and I'm starting to wonder if this isn't a bug or something similar
The QTextEdit can't accept such a big amount of text at one piece. Split it, for example like this:
if (!fileName.isEmpty()) {
QFile file(fileName);
if (file.open(QFile::ReadOnly | QFile::Text))
{
QByteArray a = file.readAll();
QString s = a.mid(0, 3000);//note that I split the array into pieces of 3000 symbols.
//you will need to split the whole text like this.
QString s1 = a.mid(3000,3000);
editor->setPlainText(s);
editor->append(s1);
}
It seems that the QTextEdit control needs time after each loading, setting a QApplication:processEvents(); after setPlainText() solves the problem although it's not an elegant solution.