Qt ignores CSS in QTextDocument - qt

Here is a small snippet of my code, I don't know why but Qt is ignoring the css.
QTextDocument *mTextDocument = new QTextDocument(0);
QTextEdit *textEdit = new QTextEdit(0);
mTextDocument->setDefaultStyleSheet(QString::fromUtf8("body{background-color: rgb(0,111,200);}"));
QTextCursor *_cursor = new QTextCursor(mTextDocument);
textEdit->setDocument(mTextDocument);
_cursor->insertBlock();
_cursor->insertHtml("<html><body><p>Hello world</p></body></html>");
textEdit->show();
I'm using Qt 4.8.

Your document already has html and body tags, so they are simply ignored when they are found in insertHtml.
If you were using QTextEdit::setHtml, they would be new elements and the default stylesheet would be applied to them.

Related

Clickable hyperlink in QTextEdit

I want to use QTextEdit (in read-only mode) to show a clickable hyperlink, I used to do
QTextEdit *textEdit = new QTextEdit;
QTextCursor cursor(textEdit->document());
textEdit->setTextCursor(cursor);
cursor->insertHtml("<a href=\"www.google.com\" >Google</a>");
textEdit->show();
this code will show Google as hyperlink but unable to click.
And if I used
QTextEdit *textEdit = new QTextEdit;
QTextCursor cursor(textEdit->document());
textEdit->setTextCursor(cursor);
QTextCharFormat linkFormat = cursor.charFormat();
linkFormat.setAnchor(true);
linkFormat.setAnchorHref("http://www.google.com");
linkFormat.setAnchorName("Google");
cursor.insertText("Google", linkFormat);
then nothing happen. "Google" is just normal text.
Please help me insert clickable hyperlink to QTextEdit.
Using QTextBrowser is simpler (as suggested by another answer). However, if for some reason you want to use QTextEdit, try to change the text interaction flags using setTextInteractionFlags().
I think you have to enable the Qt::LinksAccessibleByMouse flag.
See Qt::TextInteractionFlag and QTextEdit::textInteractionFlags
To have clickable hyperlink in QTextEdit, you can use
QTextCharFormat::setAnchorHref to set the link for some text
QWidget::mousePressEvent to capture mouse press event
QTextEdit::anchorAt to obtain the link
Here's the minimal working PyQt example,
import sys
from PyQt5.Qt import QDesktopServices, QUrl, QApplication, QColor, Qt
from PyQt5.QtWidgets import QTextEdit
class MyWidget(QTextEdit):
def mousePressEvent(self, e):
self.anchor = self.anchorAt(e.pos())
if self.anchor:
QApplication.setOverrideCursor(Qt.PointingHandCursor)
def mouseReleaseEvent(self, e):
if self.anchor:
QDesktopServices.openUrl(QUrl(self.anchor))
QApplication.setOverrideCursor(Qt.ArrowCursor)
self.anchor = None
app = QApplication(sys.argv)
editor = MyWidget()
cursor = editor.textCursor()
fmt = cursor.charFormat()
fmt.setForeground(QColor('blue'))
address = 'http://example.com'
fmt.setAnchor(True)
fmt.setAnchorHref(address)
fmt.setToolTip(address)
cursor.insertText("Hello world again", fmt)
editor.show()
app.exec_()
As far as I've tried, when using QTextEdit + Qt::LinksAccessibleByMouse I'm able to click on links, but no action is taken (i.e., link is not open). The only action possible is to right-click on the link and select Copy Link Location.
As mentioned, one option is using QTextBrowser. In this case you have to set the QTextBrowser::openExternalLinks property too, in order to open the link using the default browser, otherwise it will be open in the text-browser widget.
Another option, given you have a read-only text, is to use a QLabel with rich format, and using the QLabel::linkActivated signal to open the URL
label->setTextFormat(Qt::RichText);
QObject::connect(label, &QLabel::linkActivated, [](const QString & link) {
QDesktopServices::openUrl(link);
});
You can use QTextBrowser instead of QTextEdit if it read only text.
In order for setTextInteractionFlags() to work the openExternalLinks property needs to be set. Since this property is not available on QTextEdit, here is a little hack to enable it.
auto &clist = edit->children();
for each (QObject *pObj in clist)
{
QString cname = pObj->metaObject()->className();
if (cname == "QWidgetTextControl")
pObj->setProperty("openExternalLinks", true);
}
This does not address the mouse cursor, so you will still need to override mouseMoveEvent.

QTCreator Giving ListWidgetItems Multiple Attributes

So I'm using QTCreator to create a GUI for a project. I'm reading items from a file, and then those items are imported into a ListWidget with checkboxes next to each item. I was wondering if it's possible to have the checkbox along with a spin box or some other sort of numeric attribute tied to each item, and if so could you explain how?
Edit: If anyone know hows to add any of the editable text boxes instead that'd actually work even better.
This is what I'm currently doing to open/read the file:
QFile ingFile("/root/Desktop/file.txt");
ingFile.open(QIODevice::ReadOnly);
QTextStream in(&ingFile);
QStringList inglist;
QString line = in.readLine();
while(!line.isNull()){
inglist.append(line);
line = in.readLine();
}
QStringListIterator it(inglist);
while(it.hasNext()){
QListWidgetItem *listitem = new QListWidgetItem(it.next());
listitem->setCheckState(Qt::Unchecked);
ui->ingList->addItem(listitem);
}
Thanks!

How to change font of a QMessageBox in Qt?

I was trying to build a simple application with a QComboBox and a QPushButton. The idea is to populate the QComboBox with a list of all available fonts in the system. When the user selects a font and presses the QPushButton then a QMessageBox appears with the font selected. Now how to do it?
The solution is using the setFont() method of the QMessageBox
QMessageBox *msg = new QMessageBox(QMessageBox::Information, "Message with font",
"This message is in font: " + ui->comboBox->currentText(),
QMessageBox::Ok | QMessageBox::Cancel, this);
QFont font = QFont(ui->comboBox->currentText());
msg->setFont(font);
msg->exec();
Where combobox is QComboBox used.
You can use basic HTML markups when setting the text to your message box label. The markup supported by QLabel includes <font>.This method also allows more versatile formatting.
As before suggested you could use styles in your Html blocks (in my example add style to the paragraphs):
QMessageBox.about(
self,
"About",
"<font>"
"<p style='font-family: Terminal'>An simple app.</p>"
"<p style='font-family: Georgia, 'Times New Roman'>- PyQt</p>"
"<p>- Qt Designer</p>"
"<p>- Python3</p>",
)
Results in:
QMessageBox

How to change the font of a QGroupBox's title only?

I want to change the QGroupBox's title to be bold and others keep unchanged. How to change the font of a QGroupBox's title only?
Font properties are inherited from parent to child, if not explicitly set. You can change the font of the QGroupBox through its setFont() method, but you then need to break the inheritance by explicitly resetting the font on its children. If you do not want to set this on each individual child (e.g. on each QRadioButton) separately, you can add an intermediate widget, e.g. something like
QGroupBox *groupBox = new QGroupBox("Bold title", parent);
// set new title font
QFont font;
font.setBold(true);
groupBox->setFont(font);
// intermediate widget to break font inheritance
QVBoxLayout* verticalLayout = new QVBoxLayout(groupBox);
QWidget* widget = new QWidget(groupBox);
QFont oldFont;
oldFont.setBold(false);
widget->setFont(oldFont);
// add the child components to the intermediate widget, using the original font
QVBoxLayout* verticalLayout_2 = new QVBoxLayout(widget);
QRadioButton *radioButton = new QRadioButton("Radio 1", widget);
verticalLayout_2->addWidget(radioButton);
QRadioButton *radioButton_2 = new QRadioButton("Radio 2", widget);
verticalLayout_2->addWidget(radioButton_2);
verticalLayout->addWidget(widget);
Note also, when assigning a new font to a widget, "the properties from this font are combined with the widget's default font to form the widget's final font".
An even easier approach is to use style sheets - unlike with CSS, and unlike the normal font and color inheritance, properties from style sheets are not inherited:
groupBox->setStyleSheet("QGroupBox { font-weight: bold; } ");
The answer above is correct.
Here are a couple extra details which may be helpful:
1) I learned in
Set QGroupBox title font size with style sheets
that the QGroupBox::title doesn't support font properties, so you CAN'T set the title font that way. You need to do it as above.
2) I find the setStyleSheet() method to be a bit more "streamlined" than using QFont. That is, you can also do the following:
groupBox->setStyleSheet("font-weight: bold;");
widget->setStyleSheet("font-weight: normal;");
I searched for this question coming from PyQt5 not Qt directly, so here is my answer in python hoping that it will help others in the same situation as me.
# Set the QGroupBox's font to bold. Unfortunately it transfers to children widgets.
font = group_box.font()
font.setBold(True)
group_box.setFont(font)
# Restore the font of each children to regular.
font.setBold(False)
for child in group_box.children():
child.setFont(font)
At least with Qt 4.8, setting the font to 'bold' with style sheets didn't work for me.
A somewhat simpler version to set all children widgets to normal font which works also when you are using the Qt designer (ui files):
QFont fntBold = font();
fntBold.setBold( true );
ui->m_pGroup1->setFont( fntBold );
auto lstWidgets = ui->m_pGroup1->findChildren< QWidget* >();
for( QWidget* pWidget : lstWidgets )
pWidget->setFont( font() );

Does Qt Builder have a built-in tool for editing a toolbar?

Does Qt have a set of standard icons? (Like for Back,Forward, etc.)
How would I add these to a button or toolbar in Qt Creator/Designer?
I'm fairly certain you can't add the icons directly in Designer, but you can programmatically reference them using:
QIcon QStyle::standardIcon ( StandardPixmap standardIcon, const QStyleOption * option = 0, const QWidget * widget = 0 ) const
The returned QIcon should be style-appropriate based on your current style. You can see the list of standardIcons in the official documentation.

Resources