I am developing a system and for the GUI I preferred to use QT plug in for VisStudio 2012. I used a file browser once the browse button is pressed everything works fine and I select my file. Right after the process with my file is completed, another file browser pops up... Can you help me? Here is the code:
#include "istorm__v3.h"
#include <QFileDialog>
#include <QMessageBox>
#include "ui_istorm__v3.h"
#include "iStormParser.h"
using namespace std;
iStormParser * isp;
iSTORM__v3::iSTORM__v3(QWidget *parent)
: QMainWindow(parent)
{
isp=new iStormParser();
ui.setupUi(this);
//ui.pushButton->setAutoDefault(false);
connect(ui.pushButton, SIGNAL(ui.pushButton.clicked()), this, SLOT(ui.on_pushButton_clicked()));
}
iSTORM__v3::~iSTORM__v3()
{
}
void iSTORM__v3::on_pushButton_clicked()
{
QString filename = QFileDialog::getOpenFileName(this,
tr("Choose File"),
"D:\\Desktop\\iSTORM__v3\\iSTORM__v3\\",
"C Files (*.c);;H Files (*.h)");
string tmp=filename.toUtf8().constData();
unsigned found = tmp.find_last_of("/\\");
tmp=tmp.substr(found+1);
string data=isp->run("\\testFiles\\"+tmp);
ui.textEdit->setText( QString::fromStdString(data));
return;
}
This issue would probably happen if you either connect the slot to the corresponding signal twice, or you emit the same signal again in your slot invokation, or at least "quickly" somewhere after having the slot quit that would bring this user experience.
Related
How can I make a message?
I want make 2 message events. First, if is nothing include in my lineEdits and push the button. Must come error message "You have not includet the data". And second, if i include my lineEdits and push the button. Must come message "You have includet the data." But it's not work for me. If i push the button, then program saved empty json. If i push write data in lineEdits and push the button, then program saved as normal json. But no matter how I write, the programs always overwrite old json file. And I always get the logging that I have stored data.
Here is my code:
My .Cpp file:
#include "address_dialog.h"
#include "ui_address_dialog.h"
Address_Dialog::Address_Dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Address_Dialog)
{
ui->setupUi(this);
connect(ui->pb_Cancel,SIGNAL(clicked(bool)),this,SLOT(close()));
//Save data in json on click
connect(ui->pb_save,SIGNAL(clicked(bool)),
this,SLOT(on_pb_save_clicked()));
}
Address_Dialog::~Address_Dialog()
{
delete ui;
}
void Address_Dialog::SaveDat()
{
m_address.mVorname= ui->le_Vorname->text();
m_address.mNachname= ui->le_Nachname->text();
m_address.mLand= ui->le_Land->text();
m_address.mName= ui->le_Name->text();
m_address.mPassword= ui->le_Password->text();
QJsonObject json_obj;
json_obj["FirstName"]= m_address.mVorname;
json_obj["MiddleName"]= m_address.mNachname;
json_obj["Country"]= m_address.mLand;
json_obj["NickName"]= m_address.mName;
json_obj["Password"]= m_address.mPassword;
//Open the file for Recording using the path specified
QString file_path = "C:/Users/frs/Documents/test_obj.json";
QFile save_file(file_path);
save_file.open(QIODevice::WriteOnly);
//if(!save_file.open(QIODevice::WriteOnly))
//QMessageBox::warning(0,"Error","Cannot open the file");
QJsonDocument json_doc(json_obj);
QString json_string = json_doc.toJson();
if(save_file.write(json_string.toLocal8Bit()))
QMessageBox::information(0,"Saving....",
"The item has been successfully added");
else
QMessageBox::critical(0,"Error","The item cannot be added");
save_file.close();
}
void Address_Dialog::on_pb_save_clicked()
{
SaveDat();
}
That is my .H file
#ifndef ADDRESS_DIALOG_H
#define ADDRESS_DIALOG_H
#include <QDialog>
#include <QMessageBox>
#include "address.h"
#include <QFile>
#include <QJsonObject>
#include <QJsonArray>
#include <QJsonDocument>
#include <QString>
#include <QDir>
namespace Ui
{
class Address_Dialog;
}
class Address_Dialog : public QDialog
{
Q_OBJECT
public:
explicit Address_Dialog(QWidget *parent = 0);
~Address_Dialog();
Address m_address;//Creation of the Class object <=> /*QString mVorname,
// mNachname, mLand, mName, mPassword;*/
private slots:
void on_pb_save_clicked();
void SaveDat();
private:
Ui::Address_Dialog *ui;
};
#endif // ADDRESS_DIALOG_H
I found a solution. That was easy. I thanks all for response.
Here is my code:
if(ui->le_Vorname->text().isEmpty() || ui->le_Nachname->text().isEmpty() ||
ui->le_Land->text().isEmpty() || ui->le_Name->text().isEmpty() ||
ui->le_Password->text().isEmpty())
{
ui->pb_save->setEnabled(false);
QMessageBox::critical(0,"Error","The item cannot be added");
}else
{
ui->pb_save->setEnabled(true);
save_file.write(json_string.toLocal8Bit());
QMessageBox::information(0,"Saving....", "The item has been successfully added");
}
save_file.close();
New to C++ and Qt, I'm trying to use a microcontroller to send a large set of data (made up of integers and commas) over serial to be put in a .csv file for use in Excel. My mainwindow.cpp code so far (where I've put all the action for testing purposes):
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <string>
#include <QtSerialPort/QSerialPort>
#include <QString>
#include <QTextEdit>
#include <QFile>
#include <QTextStream>
QSerialPort *serial;
using namespace std;
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
serial = new QSerialPort(this);
serial->setPortName("/dev/cu.usbmodemfa131");
serial->setBaudRate(QSerialPort::Baud9600);
serial->setDataBits(QSerialPort::Data8);
serial->setParity(QSerialPort::NoParity);
serial->setStopBits(QSerialPort::OneStop);
serial->setFlowControl(QSerialPort::NoFlowControl);
serial->open(QIODevice::ReadWrite);
connect(serial, SIGNAL(readyRead()), this, SLOT(serialReceived()));
}
MainWindow::~MainWindow()
{
delete ui;
serial->close();
}
void MainWindow::serialReceived()
{
QString filename = "/Users/me/Documents/myFile/datacollecting.csv";
QFile file(filename);
QTextStream out(&file);
file.open(QIODevice::ReadWrite);
QByteArray ba;
ba = serial->readAll();
out << ba;
file.close();
}
The code however is giving me some issues. It does not work reliably at all and in the resultant file it only stores the last 10 or so (out of several thousand) characters. I have searched around but have not found a way to properly store large chunks of data over serial. Is there a better way to achieve what I'm trying to do above? New to this so any help would be greatly appreciated!
As already written in comments you should open your output file in append mode by adding QIODevice::Append flag so that all data is written to the end of the file.
You can also connect to error signal where you can inspect possible errors. See serial port enums here.
connect(serial, SIGNAL(error(QSerialPort::SerialPortError)), this, SLOT(handleError(QSerialPort::SerialPortError)));
void MainWindow::handleError(QSerialPort::SerialPortError error)
{
...
}
In my program, my users can copy a string of text from anywhere and paste it into my program. I use the simple QApplication::clipboard()->text(); function and everything works as expected. However, several of my users are having problems when trying to copy and paste on Windows 8.1
Here is how I access the clipboard text from my paste function:
QString clipboard = QApplication::clipboard()->text();
//check if the clipboard is empty
if(QApplication::clipboard()->text().isEmpty())
return;
//do something with clipboard
But if the text was copied from Notepad or Chrome, the text is ALWAYS empty. Windows 7 users have not had any problems. Not ALL Windows 8 users have this issue, it's only a handful but the issue it consistent. When copied from some other random places or within my program itself, the clipboard works fine.
I've tried using mimeData. When using the function formats(), only plain text is an available format, but the text is always empty.
The text being copied from Notepad/Chrome shows up fine in clipboard viewers and stuff and can be pasted elsewhere in other programs.
Copying and pasting is a very important feature in my program and its frustrating that my users can't copy and paste from Notepad or Chrome.
Any ideas? Thanks for your time. :)
EDIT: I tried using the "windows" style technique. There was no change. Here is my current, still unworking code:
QString clipboard = QApplication::clipboard()->text();
//check if the clipboard is empty
if(clipboard.isEmpty())
{
//might not actually be empty. Check using the other technique
if (IsClipboardFormatAvailable(CF_TEXT) && OpenClipboard(NULL))
{
HGLOBAL hGlobal = GetClipboardData(CF_TEXT) ;//hGlobal is NULL
if (hGlobal != NULL)//This never gets called because it is NULL
{
LPTSTR lpszData = (LPTSTR) GlobalLock(hGlobal) ;
if (lpszData != NULL)
{
clipboard.fromLocal8Bit((const char *)lpszData);
GlobalUnlock(hGlobal) ;
}
}
CloseClipboard() ;
}
if(clipboard.isEmpty())
return;
}
The copied text shows up fine in a clipboard viewer, but my program can't get to it no matter what:
How come GetClipboardData() isn't picking anything up? Again, the copied text CAN be pasted in any other program I've tried... just not mine. But if copied from somewhere else, it works no problem.
EDIT: With this version, When the user copies text and text gets to clipboard, a function copies the text this time to an internal text file not directly to your program, using QFile. Another function copies the text from the internal text file to your program. By this way, i think your program wouldn't have to directly deal with text in the clipboard
clipboard.h
#ifndef CLIPBOARD_H
#define CLIPBOARD_H
#include <QDialog>
#include <QClipboard>
#include <QLabel>
#include <QHBoxLayout>
#include <QTextEdit>
#include <QPushButton>
#include <QFile>
#include <QTextStream>
class ClipBoard : public QDialog {
Q_OBJECT
public:
explicit ClipBoard(QWidget *parent = 0);
~ClipBoard();
private slots:
//the functions that will copy and paste text from the text file
void copyToTextFile();
void paste();
private:
QPushButton *button;
QTextEdit *edit;
QString textFromClipBoard;
QClipboard *clipBoardText;
QString clipboard;
};
#endif // CLIPBOARD_H
clipboard.cpp
#include "clipboard.h"
#include "ui_clipboard.h"
ClipBoard::ClipBoard(QWidget *parent) : QDialog(parent) {
button = new QPushButton("&Paste Copied Text");
edit = new QTextEdit;
/*when user copies text and text gets to clipboard, the text is copied
from clipboard to a text file then copied from the text file to the
program*/
connect(button, SIGNAL(clicked()), this, SLOT(copyToNotepad()));
connect(button, SIGNAL(clicked()), this, SLOT(paste()));
QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(button);
layout->addWidget(edit);
setLayout(layout);
}
/*This function copies text from the clipboard to an internal text file
created by the program*/
void ClipBoard::copyToTextFile() {
clipboard = QApplication::clipboard()->text();
QFile output("out.txt");
if (output.open(QIODevice::ReadWrite | QFile::Truncate |
QIODevice::Text)) {
QTextStream out(&output);
out << clipboard;
}
}
/*This function then copies the text from the internal text file and pastes
it to the text edit. So the program doesn't have to deal directly with the
clipboard*/
void ClipBoard::paste() {
QFile input("out.txt");
if (input.exists()) {
if (input.open(QIODevice::ReadOnly | QIODevice::Text)) {
QTextStream in(&input);
clipboard = in.readAll();
}
}
edit->setText(clipboard);
}
ClipBoard::~ClipBoard() {
}
main.cpp
#include "clipboard.h"
#include <QApplication>
int main(int argc, char *argv[]) {
QApplication a(argc, argv);
ClipBoard w;
w.show();
return a.exec();
}
Look through and compare with your part of the code to see if there's something you did wrong. But as to how you claim it works on some Windows 8.1 systems and don't on others baffles me.
I had similar issue,
the solution for me is sleep.
void MainWindow::on_clipboard_change(){
QThread::msleep(1); //without this line I get allways empty clipboard
QString text = QGuiApplication::clipboard()->text();
qDebug() << "clipboard change event triggered ( " << text << " )";
}
Is there any cross platform way to get the current username in a Qt C++ program?
I've crawled the internet and the documentation for a solution, but the only thing I find are OS dependent system calls.
I was actually thinking about it a couple of days ago, and I came to the conclusion of having different alternatives, each with its own trade-off, namely:
Environment variables using qgetenv.
The advantage of this solution would be that it is really easy to implement. The drawback is that if the environment variable is set to something else, this solution is completely unreliable then.
#include <QString>
#include <QDebug>
int main()
{
QString name = qgetenv("USER");
if (name.isEmpty())
name = qgetenv("USERNAME");
qDebug() << name;
return 0;
}
Home location with QStandardPaths
The advantage is that, it is relatively easy to implement, but then again, it can go unreliable easily since it is valid to use different username and "entry" in the user home location.
#include <QStandardPaths>
#include <QStringList>
#include <QDebug>
#include <QDir>
int main()
{
QStringList homePath = QStandardPaths::standardLocations(QStandardPaths::HomeLocation);
qDebug() << homePath.first().split(QDir::separator()).last();
return 0;
}
Run external processes and use platform specific APIs
This is probably the most difficult to implement, but on the other hand, this seems to be the most reliable as it cannot be changed under the application so easily like with the environment variable or home location tricks. On Linux, you would use QProcess to invoke the usual whoami command, and on Windows, you would use the GetUserName WinAPI for this purpose.
#include <QCoreApplication>
#include <QProcess>
#include <QDebug>
int main(int argc, char **argv)
{
// Strictly pseudo code!
#ifdef Q_OS_WIN
char acUserName[MAX_USERNAME];
DWORD nUserName = sizeof(acUserName);
if (GetUserName(acUserName, &nUserName))
qDebug << acUserName;
return 0;
#elif Q_OS_UNIX
QCoreApplication coreApplication(argc, argv);
QProcess process;
QObject::connect(&process, &QProcess::finished, [&coreApplication, &process](int exitCode, QProcess::ExitStatus exitStatus) {
qDebug() << process.readAllStandardOutput();
coreApplication.quit();
});
process.start("whoami");
return coreApplication.exec();
#endif
}
Summary: I would personally go for the last variant since, even though it is the most difficult to implement, that is the most reliable.
There is no way to get the current username with Qt.
However, you can read this links :
http://www.qtcentre.org/threads/12965-Get-user-name
http://qt-project.org/forums/viewthread/11951
I think the best method is :
#include <stdlib.h>
getenv("USER"); ///for MAc or Linux
getenv("USERNAME"); //for windows
EDIT : You can use qgetenv instead of getenv.
In QT5 and up it is possible to do the following :
QString userName = QDir::home().dirName();
`QDir::home() returns the user's home directory.
You can use qEnvironmentVariable
QString sysUsername = qEnvironmentVariable("USER");
if (sysUsername.isEmpty()) sysUsername = qEnvironmentVariable("USERNAME");
Also you can use QProcessEnvironment like this:
QProcessEnvironmentenv = QProcessEnvironment::systemEnviroment();
QString username = env.value("USER");
There is a way to get the current windows username with Qt. Here it is
mainwindow.ui
This is the form ui
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QProcess>
#include <QDir>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
this->getUser();
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::getUser()
{
QProcess *username = new QProcess();
QStringList cmdParamaters, split;
QString clean1, clean2, clean3,userName;
int cutOff, strLen;
cmdParamaters << "/c"<<"\"%USERPROFILE%\"";
username->setProcessChannelMode(QProcess::MergedChannels);
username->start("cmd.exe",cmdParamaters);
username->waitForFinished();
QString vusername (username->readAllStandardOutput());
cutOff = vusername.indexOf("'", 1);
ui->label_2->setText(vusername);
clean1 = vusername.left(cutOff);
ui->label_3->setText(clean1);
clean2 = clean1.remove(0,3);
strLen = clean2.length();
ui->label_4->setText(clean2);
clean3 = clean2.left(strLen-2);
split = clean3.split("\\");
userName = split[2]; //This is the current system username
ui->label_5->setText(userName);
delete username;
}
Output:
Code output
I have a list of textfiles in a treeview (with QFileSystemModel). If a textfile is selected and a print button is pressed. It should show a print dialog and the file should be printed out. I thought (after reading documentations and examples) it should look like this:
void berichtenhistorie::on_printButton_released()
{
QModelIndex index = ui->treeView->currentIndex();
QFileSystemModel *model = (QFileSystemModel*)ui->treeView->model();
QString path = model->filePath(index);
QString name = model->fileName(index);
QString dir = path;
dir.remove(dir.size() - name.size(), name.size());
QFile file(path);
if(file.open(QIODevice::WriteOnly | QIODevice::Text))
{
file.close();
if(file.rename(QString("%1geprint %2").arg(dir, name)))
qDebug() << "renamed";
}
//all above works correctly
QPrinter printer(QPrinter::HighResolution);
printer.setPageSize(QPrinter::A4);
printer.setOrientation(QPrinter::Portrait);
printer.setPageMargins (15,15,15,15,QPrinter::Millimeter);
printer.setFullPage(false);
printer.setOutputFileName(path);
printer.setOutputFormat(QPrinter::NativeFormat);
QPainter painter(&printer);
painter.end();
}
The renaming part (so above all the printing stuff) works as it should, no errors or anything. But I get abunch of errors at the printing error. I thought it was because of the libraries, because im using Qt5.
#include <QDirModel>
#include <QDebug>
#include <QMessageBox>
#include <QtPrintSupport/QPrintDialog>
#include <QtPrintSupport/QPrinter>
#include <QPainter>
#include <QFile>
Here are the errors:
Apparently you are using Qt5, where printing functionality has been placed in separate add on (in Qt4 it is part of QtGui module), see documentation. So you have to add to pro file this line:
QT += printsupport
This will fix your build error, but your code doesn't print yet. You have to use painter.
If you are planing to support Qt4 it should be like this
greaterThan(QT_MAJOR_VERSION, 4) {
QT += printsupport
}