How to display right-to-left written ancient characters in Qt - c++

I have a project which must support multiple ancient languages. My problem is that I have an ancient Old Turkic character (the language is written right-to-left) but I can't display the characters in a Qt Label like this:
//main.cpp
#include <QApplication>
#include <QString>
#include <QLabel>
int main(int argc, char** argv[])
{
QApplication app(argc, argv);
QString str = "\U00010C00"; // Character I wanted to display
QLabel *label = new QLabel(str);
label -> show();
return app.exec();
}
When I run this, in the label it prints a square which indicates that, I think, the character couldn't be found. How can I fix this problem?
A square is being displayed at the right of the window, so there is not a problem with the location of the character. My OS is Ubuntu 12.04 x64 and my Qt version is 5, by the way. I have the Old Turkic Unicode font.

You need to tell the label which font it should use.
QFont labelFont = QFont( "Old Turkic" );
label->setfont( labelFont );

Related

how to translate key shortcut

I cannot force QKeySequence::toString() to return translated shortcut representation despite the fact that it documentation suggests it should work. The docs say: "The strings, "Ctrl", "Shift", etc. are translated using QObject::tr() in the "QShortcut" context." but I am not completely sure what it means by shortcut context. I am probably doing something wrong...
Here is my example. To make it work, I need to copy qtbase_es.qm from Qt installation directory to my project build directory. When the translation is correctly loaded, the action in the menu correctly shows "Action Control+Intro" which is Spanish translation of the shortcut for "Action Ctrl+Enter". But the tooltip on the main window is still "Action (Ctrl+Enter)". I would expect it to be "Action (Control+Intro)", like in the menu. What am I doing wrong?
#include <QAction>
#include <QApplication>
#include <QDebug>
#include <QMainWindow>
#include <QMenuBar>
#include <QTranslator>
int main(int argc, char *argv[])
{
QTranslator spanish;
qDebug() << spanish.load("qtbase_es.qm"); // should return true if correctly loaded
QApplication a(argc, argv);
QApplication::installTranslator(&spanish);
QMainWindow w;
auto menu = new QMenu("Menu");
auto action = menu->addAction("Action");
action->setShortcutContext(Qt::ApplicationShortcut);
action->setShortcut(Qt::CTRL | Qt::Key_Enter);
w.menuBar()->addMenu(menu);
w.show();
QApplication::processEvents(); // I also tried this line but it is useless...
w.setToolTip(QString("%1 (%2)").arg(action->text(), action->shortcut().toString()));
qDebug() << action->shortcut().toString(); // WRONG: returns Ctrl+Enter but I expect Control+Intro
return a.exec();
}
The QShortcut::toString has a SequenceFormat parameter, defaulted to ProtableText. The documentation of the format states, that portable format is intended for e.g. writing to a file.
The native format is intended for displaying to the user, and only this format performs translations.
Try:
qDebug() << action->shortcut().toString(QKeySequence::NativeText);

Cmd+Plus shortcut not recognised on MacBook

I want to capture shortcut Cmd+Plus to do something (zoom something). But as I found this does not work on MacBooks because Cmd+Plus has to be pressed with holding Shift key. So instead of Cmd+Plus I got Cmd+Shift+=. What is interesting: on Windows and Linux everything works as expected (Ctrl instead of Cmd, of course).
A piece of code:
#include <QApplication>
#include <QDebug>
#include <QKeyEvent>
#include <QWidget>
class Widget : public QWidget
{
public:
void keyPressEvent(QKeyEvent *event) override {
qInfo() << event->key() << event->modifiers();
}
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
When I press Cmd+Plus (with holding Shift), this code outputs 61 QFlags<Qt::KeyboardModifier>(ShiftModifier|ControlModifier) on my MacBook. Note that 61 is decadic number of '='.
This code outputs 43 QFlags<Qt::KeyboardModifier>(ShiftModifier|ControlModifier) on Windows and Linux notebooks which also require pressing Shift. But here 43 is '+'. Which is correct.
Well, how to capture Cmd+Plus then? On all platforms (equiv. Ctrl instead of Cmd on Windows and Linux), on all possible national keyboard layouts?

QCompleter::activated disconnected after losing and gaining focus

I found a strange case which I do not understand. Maybe it is a Qt bug, maybe I am doing something wrong.
A header:
// File mylineedit.h
#pragma once
#include <QLineEdit>
#include <QDebug>
class MyLineEdit : public QLineEdit
{
Q_OBJECT
public:
explicit MyLineEdit(QWidget *parent = nullptr) : QLineEdit(parent) { }
public slots:
void onCompleterActivated(const QString& text) { qDebug() << "MyLineEdit" << text; }
};
And the main source file:
// File main.cpp
#include <QApplication>
#include <QWidget>
#include <QStringListModel>
#include <QCompleter>
#include <QVBoxLayout>
#include "mylineedit.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QWidget w;
QLineEdit* lineEdit1 = new MyLineEdit();
QLineEdit* lineEdit2 = new MyLineEdit();
auto layout = new QVBoxLayout(&w);
layout->addWidget(lineEdit1);
layout->addWidget(lineEdit2);
lineEdit1->setCompleter(new QCompleter());
auto model = new QStringListModel(QStringList() << "A" << "B" << "C");
lineEdit1->completer()->setModel(model);
QObject::connect(lineEdit1->completer(), SIGNAL(activated(QString)), lineEdit1, SLOT(onCompleterActivated(QString)));
w.show();
return a.exec();
}
Once you run this, you can get a completer with values "A", "B", "C" in the first line edit. When you select any of these values, it will print the message to the console. This is correct. But then change focus to the other line edit and then back. Try picking "A", "B", "C" again. No message is printed out, the signal/slot seems disconnected. Any ideas?
Tested with MinGW 5.3.0 and MSVC 2015 using with Qt 5.9.2.
I modified your sample slightly and tried to reproduce the behavior you described but I couldn't:
#include <QtWidgets>
int main(int argc, char **argv)
{
qDebug() << "Qt Version: " << QT_VERSION_STR;
// main application
QApplication app(argc, argv);
// setup GUI
QWidget qWin;
QVBoxLayout qVBox;
QLineEdit qEdit1;
qVBox.addWidget(&qEdit1);
QCompleter qCompl1;
QStringListModel qComplModel(QStringList() << "A" << "B" << "C");
qCompl1.setModel(&qComplModel);
qEdit1.setCompleter(&qCompl1);
QLineEdit qEdit2;
qVBox.addWidget(&qEdit2);
qWin.setLayout(&qVBox);
qWin.show();
// install signal handlers
QObject::connect(&qCompl1,
static_cast<void(QCompleter::*)(const QString&)>(
&QCompleter::activated),
[](const QString &text)
{
qDebug() << "Activated: " << text;
});
// run-time loop
return app.exec();
}
The significant differences in my sample:
I used Qt5 style signal handlers (as I'm used to).
I didn't new the Qt widgets (as I'm used to when I write minimal samples).
For me, it's hard to believe that one of these changes makes your described issue unbroken.
I compiled and tested with VS2013, Qt 5.9.2 on Windows 10 (64 bit):
I did the following interactions:
click in qEdit1
type A and click on item A in the popup menu
Output:
Activated: "A"
I continued with:
click in qEdit2
type B
click in qEdit1
erase text, type B, and click on item B in the popup menu
Output:
Activated: "B"
It works like expected.
After some conversation, I had a look at woboq.org in the source code of QLineEdit:
The interesting part is in QLineEdit::focusOutEvent:
if (d->control->completer()) {
QObject::disconnect(d->control->completer(), 0, this, 0);
}
If I read this right, all signal handlers of QLineEdit (emitted by the set completer) are disconnected. I believe this is the reason for the observed issue. (Therefore, it works for lambdas and methods of other classes.)

Qt: Getting the current application palette

I have a class that composes a palette and assigns it to the application using QApplication::instance()->setPalette(QPalette palette).
And it effectively works.
But then I try to use QPalette QApplication::instance()->palette() to extract some colours.
But here it does not work, it just returns the default palette, not the current one.
After I have discovered that it is working as supposed and described in the documentation.
And now I have just 2 questions:
Why it is working in such a strange, useless and counter-intuitive
mode?
How I can retrieve the palette which was set using
QApplication::instance()->setPalette(QPalette palette)?
P.S. No, I can't keep that palette elsewhere.
I think it is an issue of your Qt version (you marked the question as Qt 5 but didn't indicate a specific version), or you have something else in your project that is resetting the palette (you mentioned it has a large code base).
This minimum example shows correct behavior, at least with Qt 5.12.3 32bits, Windows, VS 2017:
#include <QApplication>
#include <QPalette>
#include <QDebug>
#include <QTimer>
#include <QWidget>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
const auto group = QPalette::Active;
const auto role = QPalette::Text;
auto palette = QApplication::palette();
qDebug() << "palette before:" << palette.color(group, role).name();
palette.setColor(group, role, "#123456");
qDebug() << "palette set:" << palette.color(group, role).name();
QApplication::setPalette(palette);
const auto palette2 = QApplication::palette();
qDebug() << "palette after:" << palette2.color(group, role).name();
QTimer::singleShot(100, [=]() { // check palette after the events loop has started
const auto palette3 = QApplication::palette();
qDebug() << "palette after 100ms:" << palette3.color(group, role).name();
});
QWidget w;
w.show();
return a.exec();
}
I've used QApplication::palette my self to retrieve custom palettes in different projects and had no issues at all.
QGuiApplication::setPalette is documented to change the default palette, so basically I think default palette means the palette used if a widget doesn't specify the other one; not the default system palette.
PS: I couldn't make it compile when using QApplication::instance()->setPalette since QApplication doesn't defines instance() but it falls to QCoreApplication::instance(), which obviously returns a QCoreApplication. Probably just a typo when you wrote the question, but I thought it deserved some lines. Given that the palette related methods are static, I decided to use those in the example, but I had the same results using the singleton from qApp.

c++ gui button output

i have a few questions regarding the gui of cplusplus using Qt creator
well i output an array using a forloop when user's choice is for example "1"
so in qt i created a button for that and i linked it with another window
so when i press on the button it opens another window
now i want to add the output of the forloop into this window
should i include iostream in the new window's .cpp file?
or what should i enter exactly?
in the mainwindow.cpp file here is the code i used to open a new window
void MainWindow::on_pushButton_clicked()
{
movies movies;
movies.setModal(true);
movies.exec();
}
thanks.
You should add a QTextEdit to your window (can be done via Qdesigner). And give this object a name e.g. Textout. Then in the code you should get a pointer to this object through your ui object. And you can use one of many methods to set the text of this object. setText is one option
ui->Textout->setText(Your_output_as_qstring)
Your can use QTextStream to format your text if necessary. Formating can be done with QString as well.
example:
#include <sstream>
#include <QLabel>
#include <QApplication>
int main(int argc, char *argv[])
{
std::stringstream ss;
for (auto s: {"first line", "second line"})
ss << s << std::endl;
QApplication a(argc, argv);
QLabel l;
l.setText(ss.str().c_str());
l.show();
return a.exec();
}