So i have started to learn Qt, and i got hold of Qt5 C++ GUI Programming Cookbook. I wanted to make a simple video converter, and there is a example on how to do it in the book.
But executing the code from the book gives me an error:
'Ui::MainWindow' has no member named 'filePath'
ui->filePath->setText(fileName);
^
So i guess i have to add filePath to the MainWindow, but since im new to Qt and C++ i dont know exactly how to do that.
Here is mainwindow.h
#include <QMainWindow>
#include <QFileDialog>
#include <QProcess>
#include <QMessageBox>
#include <QScrollBar>
#include <QDebug>
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
QProcess* process;
QString outputText;
QString fileName;
QString outputFileName;
private slots:
void on_pushButton_clicked();
void on_pushButton_2_clicked();
void processStarted();
void readyReadStandardOutput();
void processFinished();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
process = new QProcess(this);
connect(process, SIGNAL(started()), this,
SLOT(processStarted()));
connect(process,SIGNAL(readyReadStandardOutput()),
this,SLOT(readyReadStandardOutput()));
connect(process, SIGNAL(finished(int)), this,
SLOT(processFinished()));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pushButton_clicked()
{
QString fileName = QFileDialog::getOpenFileName(this, "OpenVideo", "", "Video Files (*.avi *.mp4 *.mov)");
ui->filePath->setText(fileName);
}
void MainWindow::on_pushButton_2_clicked()
{
QString ffmpeg = "C:/FFmpeg/bin/ffmpeg";
QStringList arguments;
fileName = ui->filePath->text();
if (fileName != "")
{
QFileInfo fileInfo = QFile(fileName);
outputFileName = fileInfo.patch() + "/" + fileInfo.completeBaseName();
if (QFile::exists(fileName))
{
//0-AVI
//1-MP4
//2-MOV
int format = ui -> fileFormat-> currentIndex();
if (format ==0)
{
outputFileName += ".avi";
}
else if (format ==1)
{
outputFileName += ".mp4";
}
else if (format ==2)
{
outputFileName += ".mov";
}
qDebug()<<outputFileName<<format;
arguments<< "-i"<<fileName<<outputFileName;
qDebug()<<arguments;
process->setProcessChannelMode(QProcess::MergedChannels);
process->start(ffmpeg,arguments);
}
else
{
QMessageBox::warning(this,"Failed", "Failed to open video file.");
}
else
{
QMessageBox::warning(this,"Failed", "Failed to open video file.");
}
}
}
void MainWindow::processStarted()
{
qDebug() << "Process started.";
ui->browseButton->setEnabled(false);
ui->fileFormat->setEditable(false);
ui->convertButton->setEnabled(false);
}
void MainWindow::readyReadStandardOutput()
{
outputText += process->readAllStandardOutput();
ui->outputDisplay->setText(outputText);
ui->outputDisplay->verticalScrollBar()->setSliderPosition(ui->outputDisplay->verticalScrollBar()->maximum());
}
void MainWindow::processFinished()
{
qDebug() << "Process finished.";
if (QFile::exists(outputFileName))
{
QMessageBox::information(this, "Success", "Videosuccessfully converted.");
}
else
{
QMessageBox::information(this, "Failed", "Failed to convertvideo.");
}
ui->browseButton->setEnabled(true);
ui->fileFormat->setEditable(true);
And mainwindow.ui
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>404</width>
<height>334</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralWidget">
<widget class="QLineEdit" name="lineEdit">
<property name="geometry">
<rect>
<x>10</x>
<y>30</y>
<width>281</width>
<height>21</height>
</rect>
</property>
</widget>
<widget class="QPushButton" name="pushButton">
<property name="text">
<string>Browse</string>
</property>
</widget>
<widget class="QComboBox" name="comboBox">
<property name="geometry">
<rect>
<x>10</x>
<y>60</y>
<width>371</width>
<height>22</height>
</rect>
</property>
<item>
<property name="text">
<string>AVI</string>
</property>
</item>
<item>
<property name="text">
<string>MP4</string>
</property>
</item>
<item>
<property name="text">
<string>MOV</string>
</property>
</item>
</widget>
<widget class="QTextEdit" name="textEdit">
<property name="geometry">
<rect>
<x>10</x>
<y>100</y>
<width>371</width>
<height>141</height>
</rect>
</property>
</widget>
<widget class="QPushButton" name="pushButton_2">
<property name="geometry">
<rect>
<x>10</x>
<y>250</y>
<width>371</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>Convert</string>
</property>
</widget>
</widget>
<widget class="QMenuBar" name="menuBar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>404</width>
<height>21</height>
</rect>
</property>
</widget>
<widget class="QToolBar" name="mainToolBar">
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
</widget>
<widget class="QStatusBar" name="statusBar"/>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>
<connections/>
</ui>
The error is in the .ui file. You need to open Designer, click in your filePath, and change its name to filePath. Currently, it is textEdit.
All visual controls that you put on the .ui file via the Designer application should match the names you are using in the C++ code to access them.
Related
I'm new to QT and I've watched some tutorials about how to create a widget app. In most of them, I had to modify label text using:
ui->label->setText("smthg");
I've tried the same thing with QTextEdit and can't seem have access to it.
Tried ui->help_plz, says "no member named "textEdit" in UI::MainWindow".
How can I access QTextEdit and copy text from it?
Code:
main window.ui:
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>550</width>
<height>368</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralWidget">
<widget class="QPushButton" name="pushButton">
<property name="geometry">
<rect>
<x>140</x>
<y>210</y>
<width>114</width>
<height>32</height>
</rect>
</property>
<property name="text">
<string>PushButton</string>
</property>
</widget>
<widget class="QLabel" name="succ">
<property name="geometry">
<rect>
<x>200</x>
<y>100</y>
<width>59</width>
<height>16</height>
</rect>
</property>
<property name="text">
<string>TextLabel</string>
</property>
</widget>
<widget class="QLineEdit" name="help_plz">
<property name="geometry">
<rect>
<x>230</x>
<y>60</y>
<width>113</width>
<height>21</height>
</rect>
</property>
</widget>
</widget>
<widget class="QMenuBar" name="menuBar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>550</width>
<height>22</height>
</rect>
</property>
</widget>
<widget class="QToolBar" name="mainToolBar">
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
</widget>
<widget class="QStatusBar" name="statusBar"/>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>
<connections/>
</ui>
main.cpp:
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
mainwidow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QTextEdit>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pushButton_clicked()
{
ui->succ->setText("yeah");
ui->help_plz //no member named "help_plz" in UI::MainWindow
}
main.h:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void on_pushButton_clicked();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
It says no member named "textEdit" in UI::MainWindow because there isn't anything called textEdit in your .ui file (you can search it yourself to confirm it). You cannot access UI elements that are not there. Add a line edit to your ui file.
QMainWindows can be tricky. You need to set your central widget explicitly:
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
setCentralWidget(ui->centralWidget);
}
void MainWindow::on_pushButton_clicked()
{
ui->succ->setText("yeah");
ui->help_plz->setText("xxx"); //no member named "help_plz" in UI::MainWindow
}
This should compile (though I doubt it does what you want). FWIW: note that this exercise would have been more straightforward had you used QWidget instead of QMainWindow as your UI.
I am trying to make a simple character counter, like the one in twitter, in QT specifically with the QLineEdit feature. Ideally, it should record the number of characters entered in a QLineEdit and display the number recorded in a separate display label. For example, spotify has a character counter when naming and adding a description to a playlist.
The function that I have declared to count the number of characters entered in the QLineEdit is defined like so:
void MainWindow::countChar()
{
QString tempString = ui->displayLabel->text(); //temp variable to hold the lineEdit's text
int output = tempString.size(); //to get the number of characters in the lineEdit
QString s = QString::number(output);//convert an int to QString
ui->CharCounter->setText(s); //display the number in the displayLabel(CharCounter)
ui->CharCounter->adjustSize();
}
I call this function in my main.cpp under the object, w.
w.countChar();
The reason I want to create a character counter function is because I have set a character limit for the QLineEdit so whatever the user enters can be filled into the main displayLabel at the minimum size of the window. I have done that by writing another function:
void MainWindow::setlineInputTextCharLimit(int limit)
{
ui->inputText->setMaxLength(limit);
}
Which I called under the same object, w:
w.setLineInputTextCharLimit(200);
QTCreator is able to successfully build but the charCounter displayLabel does not change in value after I enter some amount of text into the QLineEdit.
image of the application built
It is clear that the displayLabel for the character counter is being read and has been activated however when I enter any amount of text, the value does not change.
The result after there is some text entered into the QLineEdit
So if the displayLabel is registered and a value is being shown, the function should be working but there is definitely something wrong with it too because the value not change to anything from that '0'?.
Edit: the UI file:
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>554</width>
<height>463</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralWidget">
<widget class="QWidget" name="layoutWidget">
<property name="geometry">
<rect>
<x>80</x>
<y>20</y>
<width>311</width>
<height>211</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLineEdit" name="inputText"/>
</item>
<item>
<widget class="QPushButton" name="textBtn">
<property name="text">
<string>Display Text</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="displayLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>100</width>
<height>100</height>
</size>
</property>
<property name="text">
<string/>
</property>
<property name="scaledContents">
<bool>true</bool>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="CharCounter">
<property name="enabled">
<bool>true</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="text">
<string/>
</property>
<property name="scaledContents">
<bool>true</bool>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
<widget class="QMenuBar" name="menuBar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>554</width>
<height>22</height>
</rect>
</property>
</widget>
<widget class="QToolBar" name="mainToolBar">
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
</widget>
<widget class="QStatusBar" name="statusBar"/>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>
<connections/>
</ui>
And heres the signal-slot connection:
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
connect(ui->textBtn, &QPushButton::clicked, this, &MainWindow::setText);
connect(ui->inputText, &QLineEdit::textChanged, this, &MainWindow::countChar);
}
If you want to count the texts you must count each time the text changes and for that you must use the textChanged() signal, in the following code I show an example:
#include <QApplication>
#include <QLabel>
#include <QLineEdit>
#include <QVBoxLayout>
#include <QWidget>
class CounterWidget: public QWidget
{
Q_OBJECT
Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged)
Q_PROPERTY(int maxLenght READ maxLenght WRITE setMaxLenght)
Q_PROPERTY(int length READ length)
public:
CounterWidget(QWidget *parent=nullptr):
CounterWidget(200, parent)
{
}
CounterWidget(int maxLength, QWidget *parent=nullptr):
QWidget(parent),
layout(this)
{
layout.addWidget(&lineEdit);
layout.addWidget(&counterLabel, 0, Qt::AlignTop | Qt::AlignRight);
connect(&lineEdit, &QLineEdit::textChanged, this, &CounterWidget::countChar);
connect(&lineEdit, &QLineEdit::textChanged, this, &CounterWidget::textChanged);
lineEdit.setMaxLength(maxLength);
countChar("");
}
QString text() const{
return lineEdit.text();
}
void setText(const QString &text){
lineEdit.setText(text);
}
int maxLenght() const{
return lineEdit.maxLength();
}
void setMaxLenght(int maxLenght){
lineEdit.setMaxLength(maxLenght);
}
int length() const{
return lineEdit.text().size();
}
signals:
void textChanged(const QString & text);
private slots:
void countChar(const QString & text){
QString text_label = QString("%1/%2").arg(text.size()).arg(lineEdit.maxLength());
counterLabel.setText(text_label);
}
private:
QVBoxLayout layout;
QLineEdit lineEdit;
QLabel counterLabel;
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
CounterWidget w;
w.show();
return a.exec();
}
#include "main.moc"
I was reading the text from QLabel and not QLineEdit. So the part in my code:
QString tempString = ui->displayLabel->text();
was only reading the text from the label when I wanted to read the text entered in the QLineEdit. So I changed the code to:
QString tempString = ui->inputText->text();
and that fixed the problem.
Thanks #FrozenM and #eyllanesc
Im working on a simple project in QtCreator where you input text into a line_edit which then gets printed after clicking a button. It works but I need to resize the window in order to see the updated/changed display.
So starting off with the main.cpp, I have left it as default after some tests:
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
That has the issue I was talking about above. I decided to add w.update(); and see if that fixed the issue, it did not. I thought maybe it was because the program was not looping, so I entered the code in a while(true) loop which also was to no avail.
The mainwindow.cpp file is as follows:
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
connect(ui->textBtn, SIGNAL(clicked(bool)), this, SLOT(setText()));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::setText()
{
QString temp = ui->inputText->text();
ui->displayLabel->setText(temp);
}
MainWindow.hpp:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
public slots:
void setText();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
Is there a QObject or predifined function in QT that allows me to update the window or automatically updates the window after a detected user change?
Edit: The UI file might be of importance as well:
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>554</width>
<height>463</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralWidget">
<widget class="QLabel" name="displayLabel">
<property name="geometry">
<rect>
<x>140</x>
<y>150</y>
<width>251</width>
<height>91</height>
</rect>
</property>
<property name="text">
<string/>
</property>
<property name="scaledContents">
<bool>true</bool>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
<widget class="QWidget" name="layoutWidget">
<property name="geometry">
<rect>
<x>130</x>
<y>30</y>
<width>251</width>
<height>81</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLineEdit" name="inputText"/>
</item>
<item>
<widget class="QPushButton" name="textBtn">
<property name="text">
<string>Display Text</string>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
<widget class="QMenuBar" name="menuBar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>554</width>
<height>22</height>
</rect>
</property>
</widget>
<widget class="QToolBar" name="mainToolBar">
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
</widget>
<widget class="QStatusBar" name="statusBar"/>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>
<connections/>
</ui>
The problem is not the update of the GUI but the QLabel does not change size, the initial size depends on the initial text, and if you set a text with larger size only part of the text will be displayed. To adjust the size of the label to the size of the text you must use adjustSize():
void MainWindow::setText()
{
QString temp = ui->inputText->text();
ui->displayLabel->setText(temp);
ui->displayLabel->adjustSize();
}
On the other hand in Qt5 it is advisable to use the new connection syntax since they have several advantages as indicated by the docs, in your case you must change your code to:
connect(ui->textBtn, &QPushButton::clicked, this, &MainWindow::setText);
I'm very new to Qt and also to c++. I tried to do a little Celsius/Fahrenheit converter. On the UI I use QDial and QLCDNumber to respectively change and show the temperature.
Unfortunately only the "standard connect" works:
connect(ui->celsiusDial, SIGNAL(valueChanged(int)), ui->celsiusLcd,SLOT(display(int)));
Spinning the dial leads to change on the LCD-Widget but anything else doesn't work (see the connect(...) calls in dialog.cpp.
The project have a QWidget with the name Dialog that calls the tempconverter.cpp class.
Dialog.cpp:
#include "dialog.h"
#include "ui_dialog.h"
#include "tempconverter.h"
Dialog::Dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog)
{
ui->setupUi(this);
TempConverter tempConverterObject(0, this);
TempConverter * tempConverter = &tempConverterObject;
connect(ui->celsiusDial, SIGNAL(valueChanged(int)), tempConverter, SLOT(setTempCelsius(int)));
connect(ui->celsiusDial, SIGNAL(valueChanged(int)), ui->celsiusLcd, SLOT(display(int)));
connect(tempConverter, SIGNAL(tempCelsiusChanged(int)), ui->celsiusDial, SLOT(setValue(int)));
connect(ui->fahrenheitDial, SIGNAL(valueChanged(int)), tempConverter, SLOT(setTempFahrenheit(int)));
connect(ui->fahrenheitDial, SIGNAL(valueChanged(int)), ui->fahrenheitLcd, SLOT(display(int)));
connect(tempConverter, SIGNAL(tempFahrenheitChanged(int)), ui->fahrenheitDial, SLOT(setValue(int)));
}
Dialog::~Dialog()
{
delete ui;
}
Here's my TempConverter-class:
Header: tempconverter.h
#ifndef TEMPCONVERTER_H
#define TEMPCONVERTER_H
#include <QObject>
class TempConverter : public QObject
{
Q_OBJECT
public:
TempConverter(int tempCelsius, QObject *parent = 0);
int tempCelsius() const; // const is signature for getters!(that's why they are blue!)
int tempFahrenheit() const;
public slots:
void setTempCelsius(int);
void setTempFahrenheit(int);
signals:
void tempCelsiusChanged(int); // Signals are only declared not "implemented", they are emitted when a event occurs
void tempFahrenheitChanged(int); // Signals are only declared not "implemented", they are emitted when a event occurs
private:
int m_tempCelsius; // internal representation of celsiusTemp <=> Java Attribute
};
#endif // TEMPCONVERTER_H
Class: tempconverter.cpp
#include "tempconverter.h"
#include <QDebug>
TempConverter::TempConverter(int tempCelsius, QObject *parent) : QObject(parent) // this is the constructor
{
qDebug("default constructor");
m_tempCelsius = tempCelsius;
}
void TempConverter::setTempCelsius(int tempCelsius)
{
//qDebug("setTempCelsius");
if(m_tempCelsius == tempCelsius)
return;
m_tempCelsius = tempCelsius;
emit tempCelsiusChanged(m_tempCelsius);
emit tempFahrenheitChanged(tempFahrenheit());
}
void TempConverter::setTempFahrenheit(int tempFahrenheit){
qDebug("setTempFahrenheit");
int tempCelsius = (5.0/9.0)*(tempFahrenheit-32);
setTempCelsius(tempCelsius);
qDebug("setTempFahrenheit");
}
int TempConverter::tempCelsius() const{
return m_tempCelsius;
}
int TempConverter::tempFahrenheit() const{
return (m_tempCelsius*2)+30;
}
And finally my UI looks like this: dialog.ui
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Dialog</class>
<widget class="QDialog" name="Dialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<widget class="QWidget" name="">
<property name="geometry">
<rect>
<x>30</x>
<y>40</y>
<width>331</width>
<height>231</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Celsius</string>
</property>
<widget class="QDial" name="celsiusDial">
<property name="geometry">
<rect>
<x>0</x>
<y>30</y>
<width>161</width>
<height>141</height>
</rect>
</property>
</widget>
<widget class="QLCDNumber" name="celsiusLcd">
<property name="geometry">
<rect>
<x>3</x>
<y>172</y>
<width>161</width>
<height>41</height>
</rect>
</property>
</widget>
</widget>
</item>
<item row="0" column="1">
<widget class="QGroupBox" name="groupBox_2">
<property name="title">
<string>Fahrenheit</string>
</property>
<widget class="QDial" name="fahrenheitDial">
<property name="geometry">
<rect>
<x>0</x>
<y>20</y>
<width>161</width>
<height>141</height>
</rect>
</property>
</widget>
<widget class="QLCDNumber" name="fahrenheitLcd">
<property name="geometry">
<rect>
<x>0</x>
<y>170</y>
<width>161</width>
<height>41</height>
</rect>
</property>
</widget>
</widget>
</item>
</layout>
</widget>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>
<connections/>
</ui>
Thanks in advance, I really have no clue where the error is coming from.
The problem is that the tempConverterObject variable only exists in the constructor since it has been created in that context, ie it is a local variable and it is removed from memory when that function is executed. The solution is to convert that variable to a member of the class:
*.h
private:
Ui::Dialog *ui;
TempConverter *tempConverter;
*.cpp
Dialog::Dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog)
{
ui->setupUi(this);
tempConverter = new TempConverter(0, this);
connect(ui->celsiusDial, SIGNAL(valueChanged(int)), tempConverter, SLOT(setTempCelsius(int)));
connect(ui->celsiusDial, SIGNAL(valueChanged(int)), ui->celsiusLcd, SLOT(display(int)));
connect(tempConverter, SIGNAL(tempCelsiusChanged(int)), ui->celsiusDial, SLOT(setValue(int)));
connect(ui->fahrenheitDial, SIGNAL(valueChanged(int)), tempConverter, SLOT(setTempFahrenheit(int)));
connect(ui->fahrenheitDial, SIGNAL(valueChanged(int)), ui->fahrenheitLcd, SLOT(display(int)));
connect(tempConverter, SIGNAL(tempFahrenheitChanged(int)), ui->fahrenheitDial, SLOT(setValue(int)));
}
I want a user to select an input file (eg. ~/MySampleTextFile.txt) and then select an output directory. I want the program to then copy the input file to the output directory. I was wondering how I can access the input file and output directory as input to the on_runButton_clicked() function below? Thanks for your help.
UI of program
mainwindow.h:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QString>
extern std::string selected_output_dir;
using namespace std;
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
QString on_inputFileNameButton_clicked();
void on_runButton_clicked();
QString on_outputDirButton_clicked();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
main.cpp:
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
mainwindow.cpp:
#include "mainwindow.h"
#include "ui_mainwindow.h"
# include <QFileDialog>
# include <QMessageBox>
# include <QString>
# include <QProcess>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
QString MainWindow::on_inputFileNameButton_clicked()
{
QString filename=QFileDialog::getOpenFileName(
this,
tr("Select file to analyze"),
"~",
"All files (*.*);; Text file (*.txt)"
);
// Qstring selected_output_dir = filename;
QMessageBox::information(this,tr("File Name"),filename);
return filename;
}
void MainWindow::on_runButton_clicked()
{
QString input_file_name = "/Users/Shared/MySampleTextFile.txt";
QMessageBox::information(this,tr("File Name"),input_file_name);
QString output_dir = "/home/";
QString command_to_call = "cp " + input_file_name +" " + output_dir; // copy the input_file_name to output_dir
QProcess::execute (command_to_call);
}
QString MainWindow::on_outputDirButton_clicked()
{
QString output_dir = QFileDialog::getExistingDirectory(this, tr("Open Directory"),
"",
QFileDialog::ShowDirsOnly
| QFileDialog::DontResolveSymlinks);
QMessageBox::information(this,tr("Output directory"),output_dir);
return output_dir;
}
mainwindow.ui:
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>someProgramv0.1</string>
</property>
<widget class="QWidget" name="centralWidget">
<widget class="QPushButton" name="runButton">
<property name="geometry">
<rect>
<x>150</x>
<y>160</y>
<width>115</width>
<height>32</height>
</rect>
</property>
<property name="text">
<string>Run</string>
</property>
</widget>
<widget class="QLabel" name="mainProgramTitle">
<property name="geometry">
<rect>
<x>130</x>
<y>70</y>
<width>141</width>
<height>16</height>
</rect>
</property>
<property name="text">
<string><html><head/><body><p><span style=" font-size:14pt; font-weight:600; font-style:italic; color:#ff0000;">SomeProgram v0.1</span></p></body></html></string>
</property>
</widget>
<widget class="QWidget" name="layoutWidget">
<property name="geometry">
<rect>
<x>80</x>
<y>130</y>
<width>269</width>
<height>32</height>
</rect>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QPushButton" name="inputFileNameButton">
<property name="text">
<string>Input File</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="outputDirButton">
<property name="text">
<string>Output Folder</string>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
<widget class="QToolBar" name="mainToolBar">
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
</widget>
<widget class="QMenuBar" name="menuBar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>22</height>
</rect>
</property>
<widget class="QMenu" name="menu_File">
<property name="title">
<string>&File</string>
</property>
</widget>
<addaction name="menu_File"/>
</widget>
<widget class="QStatusBar" name="statusBar"/>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>
<connections/>
</ui>
You can store filename and output_dir like this (in private section of MainWindow):
mainwindow.h:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
...
private:
Ui::MainWindow *ui;
QString filename_;
Qstring output_dir_;
};
#endif // MAINWINDOW_H
And use it like this in on_runButton_clicked():
mainwindow.cpp:
#include "mainwindow.h"
#include "ui_mainwindow.h"
...
QString MainWindow::on_inputFileNameButton_clicked()
{
filename_ =QFileDialog::getOpenFileName(
this,
tr("Select file to analyze"),
"~",
"All files (*.*);; Text file (*.txt)"
);
// Qstring selected_output_dir = filename;
QMessageBox::information(this,tr("File Name"),filename_);
return filename;
}
void MainWindow::on_runButton_clicked()
{
QString command_to_call = "cp " + filename_ +" " + output_dir_; // copy the input_file_name to output_dir
QProcess::execute (command_to_call);
}
QString MainWindow::on_outputDirButton_clicked()
{
output_dir_ = QFileDialog::getExistingDirectory(this, tr("Open Directory"),
"",
QFileDialog::ShowDirsOnly
| QFileDialog::DontResolveSymlinks);
QMessageBox::information(this,tr("Output directory"),output_dir);
return output_dir;
}
I think this is what you are after. It copies the file to the new directory with the same name and removes the old one
Use QFile
QString inputFile = QFileDialog::getOpenFileName(this, tr("Select File"), QDir::currentPath(), "All files" (*.*));
QString outputDir = QFileDialog::getExistingDirectory(this, tr("Select Directory"), QDir::currentPath());
QFile file(inputFile)
QFileInfo fileInfo(file);
file.copy(outputDir + "/" + fileInfo.fileName());
file.remove();