I have problem to scrollable for my custom image Widget.
This is my custom image Widget.
imagewidget.h:
#ifndef IMAGEWIDGET_H
#define IMAGEWIDGET_H
#include <QWidget>
#include <QImage>
#include <QString>
#include <QPaintEvent>
#include <QAbstractScrollArea>
class ImageWidget: public QWidget
{
public:
explicit ImageWidget(QWidget *parent = 0);
QImage m_Image;
void loadImage(const QString &fileName);
protected:
void paintEvent(QPaintEvent *event);
};
#endif // IMAGEWIDGET_H
imagewidget.cpp:
#include "imagewidget.h"
#include <QPainter>
#include <QPoint>
#include <QDebug>
#include <QScrollBar>
ImageWidget::ImageWidget(QWidget *parent): QWidget(parent)
{
}
void ImageWidget::loadImage(const QString &fileName)
{
if(!fileName.isNull()){
m_Image.load(fileName);
this->update();
qDebug()<<"Load Image"<<endl;
}
}
void ImageWidget::paintEvent(QPaintEvent *event)
{
QPainter p(this);
if(!m_Image.isNull()){
p.drawImage(QPoint(0,0),m_Image);
}
qDebug()<<"Paint Event"<<endl;
}
And this is mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QScrollArea>
#include <QString>
#include <QFileDialog>
#include <QWidget>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow),
scrollArea(new QScrollArea())
{
ui->setupUi(this);
m_Image = new ImageWidget(this);
scrollArea->setWidgetResizable(true);
scrollArea->setWidget(m_Image);
setCentralWidget(scrollArea);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_actionOpen_triggered()
{
QString fileName = QFileDialog::getOpenFileName(this, tr("Open Image"), "/", tr("Image Files (*.png *.jpg *.bmp *.tif *.tiff)"));
m_Image->loadImage(fileName);
m_Image->adjustSize();
this->update();
}
With a large image, the image cannot diplay with scroll bar.
My result is below. Thank you for reading.
You forget to set ImageWidget minimumsize.
void ImageWidget::loadImage(const QString &fileName)
{
if(!fileName.isNull()){
m_Image.load(fileName);
setMinimumSize(m_Image.size()); //add this line
this->update();
qDebug()<<"Load Image"<<endl;
}
}
ScrollArea shows scrollbars when its size is smaller than content's widget (ImageWidget in this case). You just load image and paint it on widget but not change widget's size.
:) My first answer on stackoverflow.
Related
I just started learning Qt, and I want to make a program that can output the input content to a txt file.I can just output the content in textEdit to txt file.But I don't know how to output the content selected in combo box or the content selected in radio button.
Widget.h:
#include <QWidget>
#include <QDebug>
#include <QFile>
#include <QDir>
#include <QTextStream>
#include <QIODevice>
#include <QMessageBox>
#include <QDesktopServices>
#include <QUrl>
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
public slots:
void pressBtn();
private slots:
void on_pushButton_2_clicked();
private:
Ui::Widget *ui;
};
Widget.cpp:
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
connect(ui-
>pushButton,SIGNAL(clicked(bool)),this,SLOT(pressBtn()));
}
//output the content in textEdit
void Widget::pressBtn(){
QString str=ui->textEdit->toPlainText();
QString str2=ui->textEdit_2->toPlainText();
QString str3=str+str2;
str3.replace("\n","\r\n");
qDebug()<<str3;
QFile file("C:/1.txt");
if(!file.open(QIODevice::WriteOnly|QIODevice::Append)){
QMessageBox::warning(this,tr("error"),tr("Fail to open
the file!"));
return;
}
QTextStream in(&file);
in<<str3;
QMessageBox::information(this,tr("tips"),tr("success!"));
QDesktopServices::openUrl(QUrl("C:/1.txt"));
}
Widget::~Widget()
{
delete ui;
}
void Widget::on_pushButton_2_clicked()
{
ui->textEdit_2->clear();
ui->textEdit->clear();
}
UI image:
enter image description here
I have the following code.
A method compress (), where I do the task of compressing an entire directory, I call this method from my button, with a QtConcurrent, as you can see. so far so good.
My question is, how can I display a message while compressing the folder is running.
I am using QuaZIP, for the compression process.
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
private slots:
void on_pushButton_5_clicked();
private:
Ui::Widget *ui;
void compress();
public:
};
#endif // WIDGET_H
#include "widget.h"
#include "ui_widget.h"
#include <QMessageBox>
#include <QDebug>
#include <JlCompress.h>
#include <QtConcurrent/QtConcurrent>
#include <QFuture>
Widget::Widget(QWidget *parent)
: QWidget(parent), ui(new Ui::Widget)
{
ui->setupUi(this);
}
Widget::~Widget()
{
delete ui;
}
void Widget::on_pushButton_5_clicked()
{
QGuiApplication::setOverrideCursor(Qt::WaitCursor);
QFuture<void> future=QtConcurrent::run(this,&Widget::compress);
future.waitForFinished();
QGuiApplication::restoreOverrideCursor();
QMessageBox::information(this,qApp->applicationName(),"The folder was compressed successfully.");
}
void Widget::compress()
{
if(!JlCompress::compressDir("C:/Users/Mypc/Desktop/iconos.zip", "D:/images/iconos")){
QMessageBox::warning(this,qApp->applicationName(),"Error compressing folder.");
return;
}
}
I did this, but now when the backup finishes, the entire application closes.
void Widget::on_pushButton_5_clicked()
{
QMessageBox box;
// box->setWindowFlags(Qt::Dialog | Qt::SplashScreen);
box.setStandardButtons(QMessageBox::NoButton);
box.setText("Realizando una tarea!");
box.setWindowTitle(qApp->applicationName());
box.setIcon(QMessageBox::Information);
box.setAttribute(Qt::WA_DeleteOnClose);
QFutureWatcher<void> watcher;
QFuture<void> future=QtConcurrent::run(this,&Widget::compress);
watcher.setFuture(future);
QGuiApplication::setOverrideCursor(Qt::WaitCursor);
QObject::connect(&watcher,&QFutureWatcher<void>::finished,[&](){
box.close();
box.deleteLater();
QGuiApplication::restoreOverrideCursor();
});
box.exec();
QMessageBox::information(this,qApp->applicationName(), "The folder was compressed successfully.");
}
Also try a ProgressDialog and QFutureWatcher as follows, but it doesn't compile, I get this error.
void Widget::on_pushButton_5_clicked()
{
QStringList files;
QDir dir("D:/images/iconos/uigenericicon");
files=dir.entryList(QStringList() << "*.jpg" << "*.JPG"<<"*.PNG",QDir::Files);
qInfo()<<files;
QProgressDialog pDialog;
pDialog.setLabelText("Porecessing!!");
QFutureWatcher<void> watcher;
QObject::connect(&pDialog,SIGNAL(canceled()),&watcher,SLOT(cancel()));
QObject::connect(&watcher,SIGNAL(finished()),&pDialog,SLOT(reset()));
QObject::connect(&watcher,SIGNAL(progressRangeChanged(int,int)),&pDialog,SLOT(setRange(int,int)));
QObject::connect(&watcher,SIGNAL(progressValueChanged(int)),&pDialog,SLOT(setValue(int)));
watcher.setFuture(QtConcurrent::map(files,&Widget::compress));
pDialog.exec();
if(watcher.isCanceled()){
QMessageBox::information(this,qApp->applicationName(),"You canceled.");
}else{
QMessageBox::information(this,qApp->applicationName(),"All done.");
}
}
void Widget::compress(QStringList &files)
{
if(!JlCompress::compressFiles("C:/Users/Lincoln/Desktop/iconos.zip",files)){
QMessageBox::warning(this,qApp->applicationName(),"Error al comprimir la carpeta.");
return;
}
}
so i am writing a simple video player program and i did the same steps as the lesson i am taking but when i run the program and click on functionalities like end (which is close()) and open (open file) they dont work, i used the slot triggering as per the lesson although i saw different ways of using the menubar here but i must follow this format, here is my code:
header:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QPushButton>
#include <QVideoWidget>
#include <QStyle>
#include <QMediaPlayer>
#include <QFileDialog >
namespace Ui {
class videoWidget;
}
class videoWidget : public QMainWindow
{
Q_OBJECT
QMediaPlayer *meinPlayer;
QPushButton *playButton;
QPushButton *stopButton;
public:
explicit videoWidget(QWidget *parent = 0);
~videoWidget();
private slots:
void listeUndTitelAktualisieren();
void on_action_End_triggered();
void on_action_ffnen_triggered();
void on_action_Stop_triggered();
void on_action_PlayBack_triggered();
void on_action_Pause_triggered();
private:
Ui::videoWidget *ui;
};
#endif // MAINWINDOW_H
cpp:
#include "mainwindow.h"
#include "ui_mainwindow.h"
videoWidget::videoWidget(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::videoWidget)
{
ui->setupUi(this);
meinPlayer = new QMediaPlayer(this);
meinPlayer->setMedia(QUrl::fromLocalFile("/beispiele/topologien.wmv"));
meinPlayer->play();
}
void videoWidget::listeUndTitelAktualisieren()
{
QString titel = meinPlayer->media().canonicalUrl().toLocalFile();
ui->listWidget->addItem(titel);
this->setWindowTitle("Multimedia-Player – " + titel);
connect(meinPlayer, SIGNAL(mediaChanged(QMediaContent)), this, SLOT(listeUndTitelAktualisieren()));
}
void videoWidget::on_action_End_triggered()
{
this->close();
}
void videoWidget::on_action_ffnen_triggered()
{
QFileDialog *meinDialog = new QFileDialog(this);
meinDialog->setAcceptMode(QFileDialog::AcceptOpen);
meinDialog->setWindowTitle("Datei öffnen");
meinDialog->setNameFilters(QStringList() << "Videos (*.mp4 *.wmv)" << "Audios (*.mp3)" << "Alle Dateien (*.*)");
meinDialog->setDirectory(QDir::currentPath());
meinDialog->setFileMode(QFileDialog::ExistingFile);
if (meinDialog->exec() == QDialog::Accepted) {
QString datei = meinDialog->selectedFiles().first();
meinPlayer->setMedia(QUrl::fromLocalFile(datei));
/*QString fileName = QFileDialog::getOpenFileName(this,
tr("Open Image"), "/home/jana", tr("Video & Audio Files (*.mp3 *.mp4 *.wmv)"));
*/
meinPlayer->play();
}
}
void videoWidget::on_action_Stop_triggered()
{
meinPlayer->pause();
}
void videoWidget::on_action_PlayBack_triggered()
{
meinPlayer->play();
}
void videoWidget::on_action_Pause_triggered()
{
meinPlayer->pause();
}
am pretty sure this instruction here:
connect(meinPlayer, SIGNAL(mediaChanged(QMediaContent)), this, SLOT(listeUndTitelAktualisieren()));
is not located where it should coz you are connecting the signal toa slot INSIDE of the SLOT implementation....
try moving that to the constructor of dein videoWidget
I'm trying to write GUI for a program that must perform some actions with given files. Its logic will be:
1) Program starts with one text field and one button created.
2) If I click on button, I can choose some .exe file. If the file is choosen, its path is set to the textfield that is logicaly linked with first my button.
3) If the file is choosen on previous step, a new pair of text field and button linked to it is created. The size of main window must change dynamically when a new pair is added.
How can I set the path to the file to current textfield?
I need a possibility to edit data in any text field. How to organize interface so that I could separately use QFileDialog with any pair of textfield and button.
I cant figure out how to use signals/slots in this case.
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QWidget>
#include <QGridLayout>
#include <QVBoxLayout>
#include <QLineEdit>
#include <QPushButton>
class MainWindow : public QWidget
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
void makeInterface();
private slots:
void openFile();
};
#endif
#include <QString>
#include <QFileDialog>
#include <QDebug>
#include "mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QWidget(parent)
{
makeInterface();
}
MainWindow::~MainWindow() {}
void MainWindow::openFile()
{
QString fileName = QFileDialog::getOpenFileName(
this,
tr("OpenFile"),
QDir::currentPath(),
tr("Executable Files (*.exe)"));
if (!fileName.isNull())
{
qDebug() << fileName;
}
}
void MainWindow::makeInterface()
{
QGridLayout *mainLayout = new QGridLayout;
QLineEdit *fldFilePath = new QLineEdit;
QPushButton *btnOpenFile = new QPushButton("*.exe");
connect(btnOpenFile, SIGNAL(clicked()), this, SLOT(openFile()));
mainLayout->addWidget(fldFilePath, 0, 0);
mainLayout->addWidget(btnOpenFile, 0, 1);
QPushButton *btnBuild = new QPushButton("Build");
mainLayout->addWidget(btnBuild, 5, 0);
setLayout(mainLayout);
}
You should use QSignalMapper for this.
Your code may looks like this:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QWidget>
#include <QGridLayout>
#include <QVBoxLayout>
#include <QLineEdit>
#include <QPushButton>
#include <QSignalMapper>
class MainWindow : public QWidget
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
void makeInterface();
private slots:
void openFile(QWidget* widget);
private:
QSignalMapper _mapper;
};
#endif
#include <QString>
#include <QFileDialog>
#include <QDebug>
#include "mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QWidget(parent)
{
connect(&_mapper, SIGNAL(mapped(QWidget*)), this, SLOT(openFile(QWidget*)));
makeInterface();
}
MainWindow::~MainWindow() {}
void MainWindow::openFile(QWidget* widget)
{
QString fileName = QFileDialog::getOpenFileName(
this,
tr("OpenFile"),
QDir::currentPath(),
tr("Executable Files (*.exe)"));
if (!fileName.isNull())
{
static_cast<QLineEdit*>(widget)->setText(fileName);
}
}
void MainWindow::makeInterface()
{
QGridLayout *mainLayout = new QGridLayout;
QLineEdit *fldFilePath = new QLineEdit;
QPushButton *btnOpenFile = new QPushButton("*.exe");
connect(btnOpenFile, SIGNAL(clicked()), &_mapper, SLOT(map()));
_mapper.setMapping(btnOpenFile, fldFilePath);
mainLayout->addWidget(fldFilePath, 0, 0);
mainLayout->addWidget(btnOpenFile, 0, 1);
QPushButton *btnBuild = new QPushButton("Build");
mainLayout->addWidget(btnBuild, 5, 0);
setLayout(mainLayout);
}
I have modified the Text Finder example which I got from a Qt Tutorial and made a Text Viewer. In this program, the user types in the address of the file and clicks the Search button. The program then displays the content of the text file. Below is my code.
text_finder.cpp:
#include "text_finder.h"
#include "ui_text_finder.h"
#include <QHBoxLayout>
#include <QFile>
#include <QTextStream>
#include <QFileDialog>
Text_Finder::Text_Finder(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::Text_Finder)
{
ui->setupUi(this);
}
Text_Finder::~Text_Finder()
{
delete ui;
}
void Text_Finder::loadFile(QFile file){ // I have to pass the file name as parameter.
QFile inputFile(file);
inputFile.open(QIODevice::ReadOnly);
QTextStream in(&inputFile);
QString line = in.readAll();
inputFile.close();
ui->read->setText(line);
QTextCursor cursor = ui->read->textCursor();
cursor.movePosition(QTextCursor::Start, QTextCursor::MoveAnchor, 1);
}
void Text_Finder::on_search_clicked()
{
// Code that gets the path from the text box.
loadFile();//Parameters not passed yet.
}
I have not yet entered the code which gets the name of the file from the address of the text box. I will have to pass the file to the loadFile() function which will enter the contents into the Text Edit in the center of the program. I want a solution to get the name of the file of which the user enters. For example, the user might enter, "/home/user/input.txt". The program should get the contents of that file and forward it to loadFile(). An solution with an explanation on how the various parts work is needed. I am using Qt Creator on Ubuntu 15.04 (Beta).
If i understand you correctly, the user types the full path or address of the file in the text box and you want to get just the name of the file out of the full path the user entered.
EDIT: I realized using 'QFileDialog' was the ideal way to get the file name. So this
is how i redesigned the whole code;
text_finder.h
#ifndef TEXT_FINDER_H
#define TEXT_FINDER_H
#include <QDialog>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QPushButton>
#include <QLineEdit>
#include <QTextEdit>
#include <QFile>
#include <QTextStream>
#include <QFileDialog>
class Text_Finder : public QWidget{
Q_OBJECT
public:
Text_Finder(QWidget *parent = 0);
~Text_Finder();
public slots:
void on_search_clicked();
void open();
//void loadFile(QString const &filename);
private:
void loadFile(QString const &filename);
QLineEdit *txtFileName;
QTextEdit *txtFileContents;
QString fileName;
QPushButton *search;
QPushButton *openFile;
};
#endif
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
class MainWindow : public QMainWindow {
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
};
#endif // MAINWINDOW_H
text_finder.cpp
#include "text_finder.h"
Text_Finder::Text_Finder(QWidget *parent) : QWidget(parent) {
openFile = new QPushButton("Open File");
connect(openFile, SIGNAL(clicked()), this, SLOT(open()));
txtFileName = new QLineEdit;
search = new QPushButton("&Search");
txtFileContents = new QTextEdit;
QHBoxLayout *dialogAndViewLayout = new QHBoxLayout;
dialogAndViewLayout->addWidget(openFile);
dialogAndViewLayout->addWidget(txtFileName);
dialogAndViewLayout->addStretch();
dialogAndViewLayout->addWidget(search);
QVBoxLayout *layout = new QVBoxLayout;
layout->addLayout(dialogAndViewLayout);
layout->addWidget(txtFileContents);
connect(search, SIGNAL(clicked()), this, SLOT(on_search_clicked()));
setLayout(layout);
}
Text_Finder::~Text_Finder(){
delete txtFileName;
delete txtFileContents;
delete search;
delete openFile;
}
void Text_Finder::loadFile(QString const &filename){
QFile inputFile(filename);
inputFile.open(QIODevice::ReadWrite | QIODevice::Text);
QTextStream textStream(&inputFile);
QString contents = textStream.readAll();
inputFile.close();
txtFileContents->setPlainText(contents);
}
void Text_Finder::on_search_clicked() {
loadFile(fileName);
}
/*this slot opens a file dialog. After the file has been selected, it sets
the file to the text text edit box*/
void Text_Finder::open() {
fileName = QFileDialog::getOpenFileName(this, "Open text", "/home/",
"");
txtFileName->setText(fileName);
}
mainwindow.cpp
#include "mainwindow.h"
#include "text_finder.h"
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) {
Text_Finder *textFinder = new Text_Finder;
setCentralWidget(textFinder);
}
MainWindow::~MainWindow() {
}
Finally
main.cpp
#include "text_finder.h"
#include <QApplication>
int main(int argc, char **argv){
QApplication app(argc, argv);
Text_Finder *window = new Text_Finder;
window->show();
return app.exec();
}
Unless you're going to do some programmatic editing, you do not need to use QTextCursor at all.
I suggest you have a browse through the reference manual before trying to carry on since it's clear that you are not familiar with the bare-basics of the graphical widgets you're using.
If you're only reading in a file name and then displaying the contents in plain text format, this is all you need to do. (I'm assuming your filename is entered into a QLineEdit widget and ui->read is a QTextEdit widget)
void Text_Finder::loadFile(QString const &filename){ // I have to pass the file name as parameter.
QFile inputFile(filename);
inputFile.open(QIODevice::ReadOnly);
QTextStream in(&inputFile);
QString contents = in.readAll();
inputFile.close();
ui->read->setPlainText(contents);
}
void Text_Finder::on_search_clicked()
{
QString filename = ui->filename->text();
loadFile(filename);
}
EDIT:
I've created a fully-functional remake of your code, incorporating the changes I suggested. I have compiled and tested it and it is working as per your description.
Note: In the absence of your UI file, I've created the user interface manually.
text_finder.h
#ifndef TEXT_FINDER_H
#define TEXT_FINDER_H
#include <QMainWindow>
class QLineEdit;
class QTextEdit;
class Text_Finder : public QMainWindow{
Q_OBJECT
public:
Text_Finder(QWidget *parent = 0);
~Text_Finder();
public slots:
void on_search_clicked();
private:
void loadFile(QString const &filename);
QLineEdit *txtFileName;
QTextEdit *txtFileContents;
};
#endif // TEXT_FINDER_H
main.cpp
#include "text_finder.h"
#include <QApplication>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QPushButton>
#include <QLineEdit>
#include <QTextEdit>
#include <QFile>
#include <QTextStream>
Text_Finder::Text_Finder(QWidget *parent) :
QMainWindow(parent)
{
QWidget *ui = new QWidget(this);
QHBoxLayout *hLayout = new QHBoxLayout;
txtFileName = new QLineEdit(this);
QPushButton *loadButton = new QPushButton("Load File", this);
connect(loadButton, &QPushButton::clicked, this, &Text_Finder::on_search_clicked);
hLayout->addWidget(txtFileName);
hLayout->addWidget(loadButton);
QVBoxLayout *vLayout = new QVBoxLayout(this);
vLayout->addLayout(hLayout);
txtFileContents = new QTextEdit(this);
vLayout->addWidget(txtFileContents);
ui->setLayout(vLayout);
setCentralWidget(ui);
}
Text_Finder::~Text_Finder(){
// It's not necessary to explicitly delete any widgets.
// QObject implements the Composite Pattern, which takes care of all this automatically
}
void Text_Finder::loadFile(QString const &filename){
QFile inputFile(filename);
inputFile.open(QIODevice::ReadOnly);
QTextStream in(&inputFile);
QString contents = in.readAll();
inputFile.close();
txtFileContents->setPlainText(contents);
}
void Text_Finder::on_search_clicked()
{
QString filename = txtFileName->text();
loadFile(filename);
}
int main(int argc, char **argv){
QApplication app(argc, argv);
Text_Finder w;
w.show();
return app.exec();
}
HINT for future questions: You will get better answers quicker if you include an SSCCE in your question. What I've included in this edit is a suitable example.