Trouble with getting national characters in QFileDialog working - c++

I'm trying to take start using Qt and decided to poke around this text editor first.
Everything goes fine except some strange behaviour of QFileDialog - I can not manage it to deal with national charset.
Here is what I see when running compiled binary and trying to open file:
I've tried to search the docs and qt wiki in order to get some clues, but there is nothing about i18n that could be readable for newbie like me.
So here is the problem code:
void TextEdit::fileOpen()
{
QString fn = QFileDialog::getOpenFileName(this, tr("Open File..."),
QString(), tr("HTML-Files (*.htm *.html);;All Files (*)"));
if (!fn.isEmpty())
load(fn);
}
I guess I should attach ::fromUtf8() here somehow, but have no understanding of how this should be done.
UPD
Tried to change default locale just as advised:
QLocale curLocale(QLocale("ru_RU"));
QLocale::setDefault(curLocale);
Also tried this variant:
QLocale::setDefault(QLocale(QLocale::Russian, QLocale::RussianFederation));
This did not help, problem persists.

Related

Directly executing a batch through clicked function in qt

So I'm trying to have my "button" directly execute a Batch file, important here is that I don't want it to show me a dialogue and make me chose the path, which is the problem I'm having right now with the following code
void MainWindow::on_pushButton_clicked()
{
QString filename=QFileDialog::getOpenFileName(
this,
tr("Open File"),
"C://",
"All files (*.*);;Text File (*.txt);;Music file (*.mp3)");
}
I think this is probably really simple, but i can't get it, I'm not even learning c++ at the moment but my boss asked me to create something out of my scope (wants me to create a GUI for a batch file and have them interact) and I thought of this approach, which is just creating a GUI that executes it.
I've looked at this question: asked to execute an external program with Qt
but they don't talk about how the file path can directly be added into the code, or if I should even be using Qprocess and how, and if I can pass it through "clicked" function.
I'm really inexperienced, all of the code above I got with the help of the internet, but I really don't know how to program using c++
so could someone please be kind enough to show me how a file path can be added to the code, assuming it's in C:\Users\name_goes_here\Downloads
I'd really appreciate it :D
I'd recommend using QProcess for anything "execute external program" with Qt.
You could do it like this:
void MainWindow::on_pushButton_clicked()
{
QProcess process;
process.start("C:/Users/name_goes_here/Downloads/yourfile.bat");
process.waitForFinished(); // Assuming that you do want to wait for it to finish before the code execution resumes
}
Note the "/" in the path. Only Windows uses the messed up "\" for path separation, which would require you to write "C:\\Users\\.." in any string in C++ as "\" needs to be escaped.
Luckily, Qt uses "/" as the universal separator and translates it to whatever the OS needs as required. So you should just use "/" whenever working with Qt.
This is from the Qt documentation:
Qt uses "/" as a universal directory separator in the same way that "/" is used as a path separator in URLs. If you always use "/" as a directory separator, Qt will translate your paths to conform to the underlying operating system.
And finally, if you don't know how to code in C++, shouldn't you be learning that first instead of trying to execute batch files from within a library as complex as Qt? Sounds like you're trying to do too many new things at once.
This is fairly simple merging your source and the one you linked:
void MainWindow::on_pushButton_clicked()
{
QProcess::execute(
QString::fromLatin1(
"cmd.exe /c C:\\Users\\name_goes_here\\Downloads\\file.bat"));
}
Notes:
I used QProcess::execute() instead of QProcess::start() to make things even simpler.
To achieve execution of the batch file, I pass it to cmd32.exe as this is the interpreter which is responsible.
As MCVE testQProcessBatch.cc:
// Qt header:
#include <QtWidgets>
void on_pushButton_clicked()
{
#if 0 // WORKS:
QProcess::execute(
QString::fromUtf8("cmd.exe /c C:\\Users\\Scheff\\Downloads\\testBatch.bat"));
#else // WORKS AS WELL:
QProcess::execute(
QString::fromUtf8("C:\\Users\\Scheff\\Downloads\\testBatch.bat"));
#endif // 0
}
int main(int argc, char **argv)
{
qDebug() << "Version:" << QT_VERSION_STR;
// main application
QApplication app(argc, argv);
QMainWindow qWin;
QPushButton qBtn(QString::fromLatin1("Start cmd"));
qWin.setCentralWidget(&qBtn);
qWin.show();
QObject::connect(&qBtn, &QPushButton::clicked,
&on_pushButton_clicked);
// run application
return app.exec();
}
and the test batch file testBatch.bat:
echo "This is testBatch.bat"
pause
Tested with VS2013 on Windows 10:
Thanks for contributing guys!
I tried using the QProcess method but I think I'm too inexperienced when it comes to figuring out problems associated with it (which I did face when using this method). the CMD route is probably good but I also thought it was too difficult and both of these methods didn't work for me.
Here's what I have now (thanks to Detonar and ymoreau) and and it seems to be doing the job, this might not be the most optimal approach, but it worked for me!
I included QDesktopServices and QUrl
void MainWindow::on_pushButton_clicked()
{
QString filename="C:\\Users\\Name_goes_here\\Downloads\\test.bat";(
this);
hide(); //optional
QDesktopServices::openUrl(QUrl("file:///"+filename,QUrl::TolerantMode));
}

QFileDialog showing hidden files although system setting is off

I am using the following code to show an open dialog in Qt:
QString path = QFileDialog::getOpenFileName(this, tr("Open Config File"), QDir::rootPath(), "Text Files (*.txt *.csv *.*);;");
What I realised is that this dialog also shows hidden files although the system setting for showing hidden files is turned off. It's the same if I instantiate the QFileDialog manually and show it. I also couldn't find out how to turn this off via a filter.
Does anyone know if there is a way to achieve the desired behaviour?
Looks like there is no simple(by setting some flag) solution out there. So I recommend to use the filtering which is described in other SO answer.
But in your case you might use the following condition:
if(fileModel != nullptr)
{
QFileInfo info = fileModel->fileInfo(index0);
return info.isHidden();
}
return false;

store input of line edit to string qt

I'm a beginner.I am making a simple gui program using qt in which you enter a url/website and that program will open that webpage in chrome.I used line edit in which user enters url and i used returnPressed() slot, but the problem is (it might sound stupid) that i don't know how to take the input by user and store it in a string so that i can pass that string as parameter to chrome.Is im asking something wrong.also tell me how can i save input to a txt file, i know how to do that in a console program.Is this process is same with others like text edit etc.
My mainwindow.cpp:
QString exeloc = "F:\\Users\\Amol-2\\AppData\\Local\\Google\\Chrome\\Application\\chrome.exe";
void MainWindow::on_site_returnPressed()
{
QString site;
getwchar(site);
QString space=" ";
QString result = exeloc + space + site;
QProcess::execute(result);
}
What im doing wrong.
thanks
You've got your approach slightly wrong, I can see where you're coming from though. It's actually a lot more simple than you're trying, Qt has a QDesktopServices class that allows you to interact with various system items, including open urls in the browser. There's documentation on it here.
QLineEdit has a text() function that will return a QString. So you can do something like this:
QString site = ui->site->text();
You don't have to use QProcess to open a web site in a browser. You can use QDesktopServices::openUrl static function.
Like this:
QString site = ui->site->text();
QUrl url(site);
QDesktopServices::openUrl(url);
Remember to include QDesktopServices and QUrl headers:
#include <QDesktopServices>
#include <QUrl>

qt5 designer, using fileopen, displaying file path in lineedit, is there an issue doing it this way?

just started using qt,
looked through docs, google, examples, etc.. trying to find simple examples(working mind you)
that showed how to do (imho) simple things, by themselves.
well i stumbled upon my answer and i was wondering if this approach would cause an issue later as the code becomes more complex.
there are more includes than needed for this example, but this is direct from working code.
mainwindow.h:
i added
private slots:
void vpkButton_clicked();
and after
Ui::MainWindow *ui;
i added
QLineEdit *vpkPathTxt;
in mainwindow.cpp:
after
ui->setupUi(this);
i added
connect( this->ui->vpkButton, SIGNAL( clicked() ), this, SLOT(vpkButton_clicked()) );
to connect my ui button to the proper slot, the issue was getting the string from vpkButton_clicked() to display in the line edit i made in the designer,
what ended up working for me was adding this next:
vpkPathTxt = this->ui->vpkPathTxt;
the function in my main.cpp became very easy:
(QString declarations at top outside voids)
void MainWindow::vpkButton_clicked()
{
vpkName = QFileDialog::getOpenFileName(this,
tr("Open VPK File"), "~/", tr("VPK Files (*_dir.vpk)"));
vpkPathTxt->setText(vpkName);
qDebug() << vpkName;
}
the reason i am ask is because it seems a little too easy to be reliable, and the fact that i havent seen it done like this,
any input welcome
thankyou
One problem with your slot is that you don't consider the case where the user discards the "open file" dialog. In this case, the function QFileDialog::getOpenFileName returns a null QString, so you should only proceed with your logic if the return value was not a null string:
if (!vpkName.isNull()) {
...
}
The second problem is as follows and I made some assumptions since I don't see your full code:
I guess you want to load a file using the file name the user has chosen in the dialog. But you set the file name in the line edit too, which the user can edit by hand. I also guess that the actual file loading happens in a different step (i.e. after clicking another button), so after the user has edited the file name by hand in the line edit it won't be the same than in your local variable vpkName.
When loading the file I'd read the contents of the line edit instead of the variable vpkName so the edit made by hand will be respected.
A different method is to also watch for editing of the line edit and reflect the changes in your variable too. Then it will be ok to read the variable instead of the line edit when loading the file later on.

QFileSystemModel and QTreeView - strange behavior when resetting view

I wrote this on official forums of Qt, but it seems dead, so I am going to copy-paste it here.
I am writing small program for copying files. I use QTreeView and I have inherited from QFileSystemModel, so I was able to add checkboxes to every row in the QTreeView. I also use setNameFilters method connected with QLineEdit, so user can specify what file extensions he wants to display in the QTreeView. I have spotted the following behavior:
1) When I run the program and enter extensions to filter (without touching any node from the QTreeView) everything works fine and files with extensions I have provided are only displayed (and folders of course). When I change the extensions and the view is refreshed, on my "C:/" drive everything is updated and only new set of extensions is displayed. When I expand some other drive that I didn’t touch before, it also shows files correctly.
2) When I run the program and expand let say my "C:/" and "D:/" drives I see all directories and files (expected behavior). Then I write some extensions and the view is refreshed. I expand "C:/" drive and everything works fine, only files with extensions I have provided are displayed. Then I go to "D:/" drive and here is the problem. It displays all files. It ignores the filters I have provided. When I open the "E:/" drive that I have not opened before, the files are filtered correctly as in "C:/" drive.
I have concluded, that this behavior has something to do with setRootPath method, because for my QTreeView only in "C:/" drive the filters are working correctly. All other drives that were expanded before change of filters don’t work. Those not expanded work just fine.
The question is: How to get this working, so after user changes the filters and reset() method is fired, the whole QTreeView is refreshed and not only root path and not-expanded elements? Maybe there exists some root path that have all the drives as children and it will work as expected? Or maybe I should make some virtual folder in the QTreeView called "MyComputer" and set it to be a parent for all the drives? But how to get list of all the available drives?
I hope that what I wrote is clear for you and you can help me to get this working.
Edit:
Adding some code that is relevant. If you need more just ask.
//setting up the model and view
QString rPath = "C:/";
rTree_model = new TreeModel(this); //TreeModel inherits from QFileSystemModel
rTree_model->setRootPath(rPath);
ui->rTree->setModel(rTree_model); //applies the model for the qtreeview (ui->rTree)
//(...)
//action when extensions were provided by user
QString extensions = QString(ui->extensionBox->text()); //gets extensions provided by user
QStringList filters;
if(extensions.length() > 0) {
filters = extensions.split(";", QString::SkipEmptyParts); //splits extensions provided with ';' as separator
rTree_model->setNameFilters(filters); //applies filters
ui->rTree->reset(); //resets the view
}
Try changing your root path to My Computer instead of C:/. It seems to work with QFileSystemModel in Windows 7 x64 and Qt 4.8.2, but I can't guarantee anything for other platforms.
rTree_model = new TreeModel(this);
QString rPath = model->myComputer().toString(); //causes the QFileSystemWatcher to watch every drive?
rTree_model->setRootPath(rPath);
ui->rTree->setModel(rTree_model);