I want to convert entity character(Escape character) to HTML in QT, please help me....
i.e: I want to replace " with ", > with >
=====This is my code that not worked====
QString MyApp::ReplaceString(const QString Data, const QString &Before, const QString &After)
{
QString Result = Data;
Result.replace(Before, After, Qt::CaseInsensitive);
return Result;
}
========
QTextCodec *codec = QTextCodec::codecForName("UTF-8");
QByteArray data=pReply->readAll();
QString str = codec->toUnicode((const char *)data);
str = Qt::escape(str);
str = ReplaceString(str, """, "\"");
str = ReplaceString(str,">", ">");
I'm not sure I understand what you want, just guessing. You can use QTextDocument. Try something like this:
QTextDocument text;
text.setHtml("<>"");
QString plain = text.toPlainText();
qDebug("%s.", qPrintable(plain));
Remember that QTextDocument needs the gui module.
I think this will solve your problem.
QString escaped=
QString(myhtml).replace("&","&").replace(">",">").replace("<","<");
Test escape() function:
QString plain = "#include <QtCore>"
QString html = Qt::escape(plain);
// html == "#include <QtCore>"
and convertFromPlainText() function:
QString Qt::convertFromPlainText ( const QString & plain, WhiteSpaceMode mode = WhiteSpacePre )
Hello to convert non ASCII character to &#XXX; (where XXX is a number):
/***************************************************************************//*!
* #brief Encode all non ASCII characters into &#...;
* #param[in] src Text to analyze
* #param[in,opt] force Force the characters "list" to be converted.
* #return ASCII text compatible.
*
* #note Original code: http://www.qtforum.org/article/3891/text-encoding.html
*
* #warning Do not forget to use QString::fromUtf8()
*/
QString encodeEntities( const QString& src, const QString& force=QString() )
{
QString tmp(src);
uint len = tmp.length();
uint i = 0;
while( i<len )
{
if( tmp[i].unicode() > 128 || force.contains(tmp[i]) ){
QString rp = "&#"+QString::number(tmp[i].unicode())+";";
tmp.replace(i,1,rp);
len += rp.length()-1;
i += rp.length();
}else{
++i;
}
}
return tmp;
}
/***************************************************************************//*!
* #brief Allows decode &#...; into UNICODE (utf8) character.
* #param[in] src Text to analyze
* #return UNICODE (utf8) text.
*
* #note Do not forget to include QRegExp
*/
QString decodeEntities( const QString& src )
{
QString ret(src);
QRegExp re("&#([0-9]+);");
re.setMinimal(true);
int pos = 0;
while( (pos = re.indexIn(src, pos)) != -1 )
{
ret = ret.replace(re.cap(0), QChar(re.cap(1).toInt(0,10)));
pos += re.matchedLength();
}
return ret;
}
Basic usage:
qDebug() << encodeEntities(QString::fromUtf8("éà#<>hello the world €"),QString("<>"));
// Will print: éà#<>hello the world €
qDebug() << decodeEntities("aßéplopéàçê€");
// Will print: hello world
Related
I have a problem with printing in Qt.
I have HTML code in QString variables. In this code I want to insert data from a database.
I get an error:
E:\apprendreQt\gestionstock6\vente.cpp:117: error: invalid operands of types
'const char*' and 'const char [27]' to binary 'operator+'
How can I fix this?
Here is my code:
int num_bl = ui->numeroBLlineEdit->text().toInt() ;
QString html;
QString requette = "select num_facture,date,nom,prenom,code_fiscale,designation,qte_out, prix,(qte_out * prix ) as Montant, sum(qte_out * prix) as Total from ventes join produits_en_ventes join clients join produits on ventes.vente_id = produits_en_ventes.vente_id and ventes.client_id = clients.client_id and produits_en_ventes.produit_id = produits.produit_id where ventes.client_id = :client_id ";
if(!m_db->isOpen())
QMessageBox::critical(this,tr("Inventoria Solution"),m_db->lastError().text()) ;
else{
m_query->clear();
m_query->prepare(requette);
m_query->bindValue(":client_id ", num_bl);
if(!m_query->exec())
QMessageBox::critical(this,tr("Inventoria Solution"),m_query->lastError().text()) ;
else{
html += " <table>"
"<thead>"
"<tr>"
"<th>N°</th>"
"<th>Désignation</th>"
"<th>Qte</th>"
"<th>Prix Unitaire</th>"
"<th>Montant</th>"
" </tr>"
"</thead>";
while(m_query->next())
{
int num_article = 1;
html += "<tr> <td>" + num_article + "</td> <td>"+m_query->value(5).toString()+"</td> <td>"+m_query->value(6).toInt() + "</td> <td>"+m_query->value(7).toInt() + "</td> <td>" + m_query->value(8).toInt() + "</td></tr>";
num_article++;
}
html += "<tfoot>"
"<tr>"
"<td>Total:"+ m_query->value(9).toInt()+"</td>"
"</tr>"
"</tfoot>"
"</table>";
}
print_Html(html);
}
I'm not sure about your error. However, AFAIK a Qstring cannot be concatenated with an int as such.
int myInt = 0;
QString text = "someString" + myInt; // WRONG
int myInt = 0;
QString text = "someString" + QString::number( myInt ); // CORRECT
or
int myInt = 0;
QString text = "someString" % QString::number( myInt ); // CORRECT
If you use operator+, you need to provide QString as an argument, but you use integer values instead: html += "<tr> <td>" + num_article, where num_article is declared as integer. You can replace it with, for example: QString::number(num_article). The same in this line:
"<td>Total:"+ m_query->value(9).toInt()+"</td>"
should be replaced with
"<td>Total:"+ m_query->value(9).toString()+"</td>"
in Qt5 you can use the QStringLiteral macro for each string that doesn't need to be localized to transform all the string literals from const char* (the C++ default) into QString, this will also make creation of those QStrings cheaper (on compilers that support it)
for Qt4 you can use the QString(const char*) constructor or QString::fromAscii(const char*) static function
I have implemented a code that will take input from QLineEdit and the data will be saved in a json file format.
void MainWindow::fileWriteOperationJson()
{
QString filename = "C:/Users/.../Documents/Qt/save.json";
QFile saveFile(filename);
saveFile.open(QIODevice::WriteOnly|QIODevice::Text);
if (!saveFile.open(QIODevice::WriteOnly))
{
qWarning("Couldn't open save file.");
}
QJsonObject obj; //this is the root
QJsonArray personalData;
QJsonObject json;
json["name"] = ui->nameLineEdit->text();
json["address"] = ui->addressLineEdit->toPlainText();
personalData.append(json);
obj["personalData"] = personalData;
QTextStream out(&saveFile);
out << QJsonDocument(obj).toJson(QJsonDocument::Indented);
}
Problem: When I open the json file, I want to find my data in the below format:
"name" = xyz
"address" = xyz
But, I am having result like this,
"address" = xyz
"name" = xyz
How to get this intended order?
JSON (JavaScript Object Notation) is a lightweight data-interchange format and as such, the structure is important, but the order of items is not.
If you need to print the items in a specific order, you'll need to extract them from Json into suitable data structures and handle that yourself.
Alternatively, you could save to a different format, but note that Qt's XML will act the same as Json. Perhaps a CSV may be more useful to you.
Qt generates JSON data with keys sorted alphabetically. AFAIK, there is no option to get around it. You could try encapsulating objects with a single key/value pair into an array, though, and preserve the order:
[
{"address": xyz},
{"name": xyz}
]
Or you could try using a different storage format altogether.
The underlying problem is that QMap does not have an ordered form.
Here's a possible solution by subclassing QVariantMap:
#ifndef ORDEREDVARIANTMAP_H
#define ORDEREDVARIANTMAP_H
#include <QtCore>
class OrderedVariantMap : public QMap<QString, QVariant> {
// Test:
// OrderedVariantMap test_map;
// test_map.insert("xxx", 1);
// test_map.insert("aaa", 2);
// test_map.insert("kkk", 3);
// test_map["321"] = 4;
// test_map["000"] = 5;
// test_map["123"] = 6;
// qDebug() << "QMap.keys()" << test_map.keys();
// qDebug() << "QMap.orderedKeys()" << test_map.orderedKeys();
// QVariant test_variant;
// test_variant.setValue(test_map);
// qDebug() << "test_variant.typeName()" << test_variant.typeName();
// OrderedVariantMap test_map_recovered = qvariant_cast<OrderedVariantMap>(test_variant);
// qDebug() << "test_map_recovered.orderedKeys()" << test_map_recovered.orderedKeys();
// Test results:
// QMap.keys() ("000", "123", "321", "aaa", "kkk", "xxx")
// QMap.orderedKeys() ("xxx", "aaa", "kkk", "321", "000", "123")
// test_variant.typeName() OrderedVariantMap
// test_map_recovered.orderedKeys() ("xxx", "aaa", "kkk", "321", "000", "123")
public:
OrderedVariantMap ( );
~OrderedVariantMap ( );
void
clear ( );
void // QMap::iterator
insert ( const QString &key,
const QVariant &value );
QVariant&
operator[] ( const QString &key );
const QVariant
operator[] ( const QString &key ) const;
const QString
orderedKey ( int index ) const;
const QVariant
orderedValue ( int index ) const;
QStringList
orderedKeys ( ) const ;
private:
QStringList Ordered_Keys;
protected:
};
Q_DECLARE_METATYPE(OrderedVariantMap)
#endif // ORDEREDVARIANTMAP_H
and
#include "OrderedVariantMap.h"
OrderedVariantMap::OrderedVariantMap ( ) : QMap ( ) {
}
OrderedVariantMap::~OrderedVariantMap ( ) {
}
QStringList
OrderedVariantMap::orderedKeys ( ) const {
return Ordered_Keys;
}
void
OrderedVariantMap::clear ( ) {
Ordered_Keys.clear();
QMap::clear();
}
void // QMap::iterator
OrderedVariantMap::insert ( const QString &key,
const QVariant &value ) {
Ordered_Keys.append(key);
QMap::insert(key, value);
}
QVariant&
OrderedVariantMap::operator[] ( const QString &key ) {
Ordered_Keys.append(key);
return QMap::operator [](key);
}
const QVariant
OrderedVariantMap::operator[] ( const QString &key ) const {
return this->value(key);
}
const QString
OrderedVariantMap::orderedKey ( int index ) const {
return Ordered_Keys[index];
}
const QVariant
OrderedVariantMap::orderedValue ( int index ) const {
return this->value(Ordered_Keys[index]);
}
More functionality could be provided, for example an ordered iterator.
I want to start cmd.exe from a Qt app with a specific PATH set. I insert "Path" in QProcessEnvironment and set that environment to QProcess. Then I startDetached "cmd". On the command prompt, the path is the same as the from the calling app, not what I just set. Did I miss something? I use Qt 5.2.0 with mingw and Qt-creator 3.0.0 on windows 8.1.s
QProcess process(this);
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
env.insert("Path", "MyPath");
process.setProcessEnvironment(env);
QStringList args;
args << "/D" << "/K" << "dir";
process.startDetached("cmd", args);
The startDetached method is a static method. So all the state that you applied to the process object is just ignored, because the method cannot see it. If you start the process with start() instead, the new process will pick up your environment.
process.start("cmd", args);
Of course, you want to the new process to be detached so that the parent can terminate without forcing the new process also to terminate. From what I can tell, the QProcess class does not offer you a way to achieve that easily. You could modify the environment of the parent process so that the new process inherits those modifications, but that does not sound at all desirable.
This question presents a possible workaround: Detaching a started process.
As David answered startDetached doesn't use the environment. So I went and take the original code and adjusted it a bit so it works (for me at least).
WProcess.h:
#ifndef WPROCESS_H
#define WPROCESS_H
#include <QProcessEnvironment>
class WProcess
{
public:
WProcess();
void setProcessEnvironment(const QProcessEnvironment &value) {environment = value;}
bool startDetached(const QString &program, const QStringList &arguments, const QString &workingDir);
private:
QProcessEnvironment environment;
};
#endif // WPROCESS_H
WProcess.cpp:
#include "WProcess.h"
#include <Windows.h>
#include <WinBase.h>
static QString w_create_commandline(const QString &program, const QStringList &arguments)
{
QString args;
if (!program.isEmpty()) {
QString programName = program;
if (!programName.startsWith(QLatin1Char('\"')) && !programName.endsWith(QLatin1Char('\"')) && programName.contains(QLatin1Char(' ')))
programName = QLatin1Char('\"') + programName + QLatin1Char('\"');
programName.replace(QLatin1Char('/'), QLatin1Char('\\'));
// add the prgram as the first arg ... it works better
args = programName + QLatin1Char(' ');
}
for (int i=0; i<arguments.size(); ++i) {
QString tmp = arguments.at(i);
// Quotes are escaped and their preceding backslashes are doubled.
tmp.replace(QRegExp(QLatin1String("(\\\\*)\"")), QLatin1String("\\1\\1\\\""));
if (tmp.isEmpty() || tmp.contains(QLatin1Char(' ')) || tmp.contains(QLatin1Char('\t'))) {
// The argument must not end with a \ since this would be interpreted
// as escaping the quote -- rather put the \ behind the quote: e.g.
// rather use "foo"\ than "foo\"
int i = tmp.length();
while (i > 0 && tmp.at(i - 1) == QLatin1Char('\\'))
--i;
tmp.insert(i, QLatin1Char('"'));
tmp.prepend(QLatin1Char('"'));
}
args += QLatin1Char(' ') + tmp;
}
return args;
}
static QByteArray w_create_environment(const QProcessEnvironment &environment)
{
QByteArray envlist;
if (!environment.isEmpty())
{
static const wchar_t equal = L'=';
static const wchar_t nul = L'\0';
int pos = 0;
QStringList keys = environment.keys();
foreach(QString key, keys)
{
QString value = environment.value(key);
uint tmpSize = sizeof(wchar_t) * (key.length() + value.length() + 2);
// ignore empty strings
if (tmpSize != sizeof(wchar_t) * 2)
{
envlist.resize(envlist.size() + tmpSize);
tmpSize = key.length() * sizeof(wchar_t);
memcpy(envlist.data() + pos, key.utf16(), tmpSize);
pos += tmpSize;
memcpy(envlist.data() + pos, &equal, sizeof(wchar_t));
pos += sizeof(wchar_t);
tmpSize = value.length() * sizeof(wchar_t);
memcpy(envlist.data() + pos, value.utf16(), tmpSize);
pos += tmpSize;
memcpy(envlist.data() + pos, &nul, sizeof(wchar_t));
pos += sizeof(wchar_t);
}
}
// add the 2 terminating 0 (actually 4, just to be on the safe side)
envlist.resize( envlist.size()+4 );
envlist[pos++] = 0;
envlist[pos++] = 0;
envlist[pos++] = 0;
envlist[pos++] = 0;
}
return envlist;
}
WProcess::WProcess()
{
}
bool WProcess::startDetached(const QString &program, const QStringList &arguments, const QString &workingDir)
{
QByteArray envlist;
if (!environment.isEmpty())
{
envlist = w_create_environment(environment);
}
QString args = w_create_commandline(program, arguments);
bool success = false;
PROCESS_INFORMATION pinfo;
STARTUPINFOW startupInfo = { sizeof( STARTUPINFO ), 0, 0, 0,
(ulong)CW_USEDEFAULT, (ulong)CW_USEDEFAULT,
(ulong)CW_USEDEFAULT, (ulong)CW_USEDEFAULT,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
success = CreateProcess(0, (wchar_t*)args.utf16(),
0, 0, FALSE, CREATE_UNICODE_ENVIRONMENT | CREATE_NEW_CONSOLE,
envlist.isEmpty() ? 0 : envlist.data(),
workingDir.isEmpty() ? 0 : (wchar_t*)workingDir.utf16(),
&startupInfo, &pinfo);
if (success)
{
CloseHandle(pinfo.hThread);
CloseHandle(pinfo.hProcess);
//if (pid) *pid = pinfo.dwProcessId;
}
return success;
}
Usage, open command prompt in C:\Qt\Qt-creator and set path to "mypath".
WProcess process;
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
env.insert("Path", "mypath");
process.setProcessEnvironment(env);
process.startDetached("cmd", QStringList(), "C:\\Qt\\Qt-creator");
Is there simple way of replacing only first occurrence of some substring by other substring in QString? It can be at any position.
You could try this:
QString str("this is a string"); // The initial string.
QString subStr("is"); // String to replace.
QString newStr("at"); // Replacement string.
str.replace(str.indexOf(subStr), subStr.size(), newStr);
Resulting string will be:
that at a string
There is no convenience method for the operation you wish to have. However, you can use the following two methods to build your custom operation:
int QString::indexOf(const QString & str, int from = 0, Qt::CaseSensitivity cs = Qt::CaseSensitive) const
Returns the index position of the first occurrence of the string str in this string, searching forward from index position from. Returns -1 if str is not found.
If cs is Qt::CaseSensitive (default), the search is case sensitive; otherwise the search is case insensitive.
and
QString & QString::replace(int position, int n, const QString & after)
Replaces n characters beginning at index position with the string after and returns a reference to this string.
Note: If the specified position index is within the string, but position + n goes outside the strings range, then n will be adjusted to stop at the end of the string.
Now, putting all that into practice, you could write something as follows:
main.cpp
#include <QString>
#include <QDebug>
int main()
{
QString initialString = QLatin1String("foo bar baz");
QString fooString = QLatin1String("foo");
initialString.replace(initialString.indexOf(fooString),
fooString.size(), QLatin1String("stuff"));
qDebug() << initialString;
return 0;
}
main.pro
TEMPLATE = app
TARGET = main
QT = core
SOURCES += main.cpp
Build and Run
qmake && make && ./main
Output
"stuff bar baz"
This is pretty much the way QString::replace(QRegularExpression, ... does it. Since it's possible that literal backslashes could be part of replace pattern, those need to be captured differently. Note that actual replacement happens right-to-left to preserve leftward offset validity. It's possible to put this more compactly, but easier to debug in this form.
QRegularExpression regex = QRegularExpression(regex_pattern);
if (regex.isValid() and
(regex_pattern.length() > 0)) {
QRegularExpressionMatchIterator regex_iterator =
regex.globalMatch(target_text, Apply_Target_Offset,
QRegularExpression::PartialPreferCompleteMatch);
if (regex_iterator.hasNext()) {
// At least one found
QRegularExpressionMatch match = regex_iterator.next();
if (match.hasMatch() and (not match.hasPartialMatch())) {
// This is the first match, and it's complete
int match_begin = match.capturedStart();
int match_end = match.capturedEnd();
int match_length = match.capturedLength();
QStringList captured;
const int capture_groups_count = regex.captureCount() + 1;
for (int capture_group_idx = 0; capture_group_idx < capture_groups_count; ++capture_group_idx) {
captured.append(match.captured(capture_group_idx));
}
QString replace_pattern = Apply_Replace_Pattern->toPlainText();
QString replace_text = replace_pattern;
QList<QRegularExpressionMatch> replace_pattern_match_list;
QRegularExpression replace_pattern_regex = QRegularExpression("(?:\\\\\\\\)+|(?:\\\\(\\d+))");
if (replace_pattern_regex.isValid()) {
QRegularExpressionMatchIterator replace_pattern_regex_iterator =
replace_pattern_regex.globalMatch(replace_pattern);
while (replace_pattern_regex_iterator.hasNext()) {
QRegularExpressionMatch replace_pattern_match = replace_pattern_regex_iterator.next();
bool no_error;
replace_pattern_match.captured().right(1).toInt(&no_error);
// Only accept backreferences w/ numbers
if (no_error) replace_pattern_match_list.append(replace_pattern_match);
}
while (replace_pattern_match_list.count() > 0) {
QRegularExpressionMatch replace_pattern_match = replace_pattern_match_list.takeLast();
int cap_idx = replace_pattern_match.captured(1).toInt();
if (cap_idx < captured.count()) {
replace_text.replace(replace_pattern_match.capturedStart(),
(replace_pattern_match.capturedEnd() -
replace_pattern_match.capturedStart()),
captured[cap_idx]);
}
}
// Render '\' characters properly
replace_text.replace("\\\\", "\\");
}
target_text.replace(match_begin, (match_end - match_begin), replace_text);
}
}
}
//------------------------------------------------------------------
QString & replace_first(QString &io_haystack, const QString & sub_str, const QString & new_str)
{
io_haystack.replace(io_haystack.indexOf(sub_str), sub_str.size(), new_str);
return io_haystack;
} // replace_first
//------------------------------------------------------------------
QString & replace_first(QString &io_haystack, const QRegularExpression & sub_regx, const QString & new_str)
{
QRegularExpressionMatch match;
match = sub_regx.match(io_haystack);
if (match.hasMatch()) {
QString sub_str = match.captured(0);
io_haystack.replace(io_haystack.indexOf(sub_str), sub_str.size(), new_str);
}
return io_haystack;
} // replace_first
How I should parse QString, which contains system variables ?What I want:
QString path = "%WINDIR%\\System32\\";
QString output = parse(path);
QDebug()<<output; \\ output is "C:\\Windows\\System32\\"
I think you want something like this:
// Untested
QString parse(QString str)
{
int pos = 0;
QRegExp rx("%([^%]+)%"); // Match env var between two '%'
rx.setMinimal(true);
while((pos = rx.indexIn(str, pos)) != -1)
{
// Replace env var
QString capture = rx.cap(1);
QString replacement = getenv(capture.toAscii());
str.replace("%" + capture + "%", replacement);
// Skip env var + two '%'
pos += rx.matchedLength() + 2;
}
return str;
}
QString path = parse("%WINDIR%\\System32");
I think, this is what you looking for. Please try this
QString windir = getenv ("WINDIR"); // Expanded
if (windir.isEmpty()) {
fprintf(stderr, "Generator requires WINDIRto be set\n");
}
windir += "\\System32";
qDebug()<<windir;