I have an application that I implemented, and want to display an image in a widget, but I get an error SIGSEGV, I view it from a directory, but in reality after heave from a buffer
not what the problem is I leave my code here:
void Image:: on_pushButton_clicked ()
{
this-> conn-> connect (this-> ui-> lineEdit_2-> text (),
this-> ui-> lineEdit-> text (). Toint ()); QLayout* layout;
QString fileName = QFileDialog:: GetOpenFileName (this,
tr ("Open File"), QDir:: currentPath (),
"files (*. jpg *. png)");
QImage image (fileName);
QLabel * label = new QLabel (this);
label-> setPixmap (QPixmap:: FromImage (image));
label-> setScaledContents (true);
layout-> addWidget (label);
label-> show ();
}
I can leave if you want to help my application link for the download
thank you very much
thank you very much and I managed to see the image, I want to load from a buffer like this: QBuffer * buffer = new QBuffer (conex);
QImage * image = new QImage ();
image-> loadFromData (buffer-> buffer ());
I tried this to make my image but I get errors
QBuffer * buffer = new QBuffer (conn);
QImage image = new QImage ();
image-> loadFromData (buffer-> buffer ());
errors are as follows:
C:\ejemplos_qt\teratermobile-build-simulator..\teratermobile\imagen.cpp:81: error: conversion from 'QImage*' to non-scalar type 'QImage' requested
C:\ejemplos_qt\teratermobile-build-simulator..\teratermobile\imagen.cpp:82: error: base operand of '->' has non-pointer type 'QImage'
You didn't initialize your layout variable before using it with something like this:
layout = new QVBoxLayout(widget); // widget is where you want to put the QLabel
or you can reuse an already created layout.
If you want to show the QLabel as a top-level window, remove completely the two lines about the layout.
Related
I'm trying to monitor changes in a folder using QFileSystemWatcher, and whenever changes happen they will be reflected in the GUI.
The idea is that I have a folder that gets updated every second with new images, and I need to display those images in sequence
nevertheless, the changes happen very fast, and the GUI freezes.
how can I make this line run in a different thread whenever there's a change in the folder.
QObject::connect(&watcher, SIGNAL(directoryChanged(QString)), w, SLOT(showModified(QString)));
or how can I make the code that creates reflections on the GUI run in a separate thread?
To make QFileSystemWatcher work in a separate thread you can do:
Create new thread - auto thread = new QThread;
Create new file system watcher - auto watcher = new QFileSystemWatcher;
Move watcher to thread - watcher->moveToThread(thread);
Make connections
connect(thread, &QThread::finished, watcher, &QObject::deleteLater);
connect(thread, &QThread::finished, thread, &QObject::deleteLater);
connect(watcher, &QFileSystemWatcher::directoryChanged, w, &<YourWidgetClassName>::showMidified, Qt::QueuedConnection);
Start thread thread->start();
Setup watcher with addPath or addPaths
Do not forget call thread->quit(); when it's not needed or before application exits
So about problem of bunch images rendering in GUI.
I suggest you to use QImage to load and scale images for QPixmap to be created and rendered in GUI. Here QtConcurrent::run can be used per image to preform an image loading in a separate thread. It returns a QFuture object, that can be tracked with a QFutureWatcher object, that emits a finished signal, when a watched future is complete. Once connected to a QFutureWatcher::finished signal you can handle QFuture's result to assign a loaded QImage to QPixmap.
So, you need a code like this for QFileSystemWatcher::directoryChanged signal handler:
QStringList filenames = <some code to get new image filenames to render>;
auto loadImage = [](const QString &aFilename) -> QPixmap {
auto image = QImage(aFilename).scaled(200, 200, Qt::KeepAspectRatio, Qt::SmoothTransformation);
return QPixmap::fromImage(image);
};
for (auto &filename : filenames) {
auto pixmap = QPixmap(200, 200); //create empty pixmap of desired size
auto label = new QLabel;
label->setPixmap(pixmap);
m_layout->addWidget(label);
auto future = QtConcurrent::run(loadImage, filename);
auto watcher = new QFutureWatcher<QPixmap>(this);
connect(watcher, &QFutureWatcher<QPixmap>::finished, this, [watcher, label]() { label->setPixmap(watcher->result()); });
connect(watcher, &QFutureWatcher<QPixmap>::finished, watcher, &QFutureWatcher<QPixmap>::deleteLater);
watcher->setFuture(future);
}
I'm new using Qt and I'm having some troubles with it.
I'm doing a simple terminal application and I need to disable the buttons for a few seconds after they are selected.
I'm doing something like this:
void MainWindow::on_readcard_clicked(){
this->setEnabled(false);
//Send Command
QString commandString = "";
commandString.append('1');
commandString.append("\n");
QByteArray commandArray = commandString.toLocal8Bit();
serial->write(commandArray);
//Read Card
QByteArray data = serial->readLine(12);
QString dataString = 0;
dataString.append(data);
ui->cardnumber->setText(dataString);
dataString.clear();
data.clear();
QByteArray saldo = serial->readAll();
QString saldoString = 0;
saldoString.append(saldo);
ui->balance->setText(saldoString);
saldoString.clear();
saldo.clear();
this->setEnabled(true);}
I need this because if someone press the button twice before it finished processing the first tap I will get a "crazy" array with lots of trash.
I also tried use "waitForBytesWritten" and "waitForReadyRead" but it hasn't blocked the connection until everything was processed.
Regards
Try with QTimer::SingleShot() :
this->setEnabled(false);
QTimer::singleShot(2000, this, SLOT(enableMyButton()));
// you code
void enableMyButton()
{
this->setEnabled(true);
}
It'll enable the button 2secs after the call
I made a push button that will browse and get a textfile. But I need to open it in a new window to check if the content of the textfile is correct. How do I do this?
Also, I would like to have a line edit right next to the button that shows which file I'm looking at. In other words, the directory of the file that is opened through the button.
Currently, this is what I have:
void MainWindow::on_fileButton_clicked()
{
QString fileName1 = QFileDialog::getOpenFileName(this,tr("Open Text File"), "", tr("Text Files (*.txt)"));
QFile file1(fileName1);
if(!file1.open(QIODevice::ReadOnly | QIODevice::Text))
return;
QTextStream in(&file1);
while(!in.atEnd()){
QString line = in.readLine();
}
}
I suggest using one of powerful text interfaces available:
void MainWindow::openfile() {
QString fileName1 = QFileDialog::getOpenFileName(this,tr("Open Text File"), "", tr("Text Files (*.txt)"));
QFile file1(fileName1);
if(!file1.open(QIODevice::ReadOnly | QIODevice::Text))
return;
// show the directory path of opened file
dir->setText(QFileInfo(file1).dir().path());
QTextBrowser *b = new QTextBrowser;
b->setText(file1.readAll());
b->show();
}
dir is a member variable, initialized in constructor with
dir = new QLineEdit(this);
you should make a new window by add a Dialog or Mainwindow. after that add widgets like textEdit and other things to your new Dialog.
you need to learn some basics of Qt framework:
there is very well documentation of Qt, you can use it.
and also there is about 100 short videos of Qt learning.
I am trying to play a video in Qt using OpenCV. I am using the following code.
CvCapture *capture;
IplImge *frame;
cv::Mat source_image;
cv::Mat dest_image;
QTimer *imageTimer;
void MainWindow::onButtonClick()
{
capture = cvCaptureFromFile("/mp.mp4");
while(capture)
{
frame = cvQueryFrame((capture);
source_image = frame;
cv::resize(source_image,source_image,cv::Size(420,180),0,0);
cv::cvtColor(source_image,source_image,CV_BGR2RGB);
QImage qimg = QImage((const unsigned char*) source_image.data,source_image.cols,source_imge.rows,QImage::Format_RGB888);
label->setPixmap(QPixmap::fromImage(qimg));
label->resize(label->pixmap()->size());
qapp->processEvents();
}
}
When I try to play it on button click it is working fine. However when I write the same code in MainWindow constructor it gets finished unexpectedly. I want that the video should be displayed on screen start up and not when I click a button. What should I do for the same?
Thank You :)
I have a QSpinBox that changes the coloring of an QImage on a scene. Everything works just fine. The color updates correctly. If i hold down the arrow on my QSpinBox everything works fine. I do have a problem when I hold down the the arrow on my QSpinBox for a very long time. When I hold it for about a minute or so, my application eventually stops responding and sometimes the image disappears. I was wondering if anyone knew what could be potentially causing this. Is it possible that my application gets too bogged down with signals? if so, how do i fix this?
Thanks for your help!
Here is a snippet of code. I haven't included the stuff for setting each pixel value. that I know I'm doing correctly. The changeMinColor is one of the slots for the signal of a spinbox.
void binFileDialog::changeMinColor(double value)
{
lowColorValue = value;
ui->maxColorSpin->setMinimum(lowColorValue + .0001);
setBinScene();
}
void binFileDialog::setBinScene()
{
float lowValue = lowColorValue;
float highValue = highColorValue;
QImage img = QImage(bFile.ncols, bFile.nrows, QImage::Format_RGB32);
// go through and set call img.setPixel with rgb values based on contents of bFile
// and the min and max colors lowValue and highValue.
QPixmap pm = QPixmap::fromImage(img);
QGraphicsScene *scene = new QGraphichsScene;
ui->graphicsView->setSceneRect(0,0, bFile.ncols, bFile.nrows);
scene->addPixmap(pm);
ui->graphicsView->setScene(scene);
}
changeMinColor is connected to the QSpinBox's valueChanged signal:
connect(ui->minColorSpin, SIGNAL(valueChanged(double)),
SLOT(changeMinColor(double)));
I have also noticed that as I hold down the spinbox my memory increases. This has to be wrong. What am I forgetting? Thanks again for the help.
setBinScene() creates a new QGraphicsScene each time which is never deleted. As each value change of the spinbox calls setBinScene(), your code piles up leaked QGraphicsScene objects.
I'd suggest to avoid recreating the scene all together and just update a QGraphicsPixmapItem instead:
Initialize the scene (once):
QGraphicsScene *scene = new QGraphicsScene(this);
m_pixmapItem = new QGraphicsPixmapItem;
scene->addItem(m_pixmapItem);
ui->graphicsView->setScene(scene);
to set/update the image:
m_pixmapItem->setPixmap(pm);
ui->graphicsView->setSceneRect(0,0, bFile.ncols, bFile.nrows); //might want to avoid this one if the dimensions do not change