How to give QTextFrame or QTextBlock a background-image in QTextEdit? - qt

I am developing an IM tool,as a part of it I have to develop a BubbleChatWidget on which all message items have a bubble-like background-image.I thought I could achieve my goal with QTextEidt,but I don't know how to give 'QTextFrame' or QTextBlock a background-image.
So my question is that how to give QTextFrame or QTextBlock a background-image in QTextEdit?If QTextEdit can't satisfy my demands, how to achieve my goal with other Qt techniques?
The BubbleChatWidget may contains clickable texts or pictures.And you can't forget the fact that the BubbleChatWidget may contains thousands of items.
The picture below displays what I want.

Qt Style Sheets are a perfect fit to achieve what you want.
The solution is to use a border image. Fortunately you can do that with style sheets and you can style QTextEdits.
About styling the QTextBlocks or QTextFrames: A QTextEdit is a widget that displays a QTextDocument which can contain QTextBlocks and QTextFrames. Frames and blocks are text containers that provide structure for the text in a document but they're not rendered by separate widgets. For that reason they can not be styled independently. What I recommend is to use a QTextEdit or other widget for each message and properly manage the consequent increase in memory use.
I'll expose how to style a text edit.
First, take a clean image of your desired border. With a little Photoshop I've prepared my own image (not as clean as it should for a production app):
Lets style objects of the class QTextEdit and its subclasses.
QTextEdit {
background-color: #eaedf2; /* Same gray in your background center */
border-image: url(":/images/bkg.png"); /* The border image */
border-top-width: 11px;
border-right-width: 4px;
border-bottom-width: 4px;
border-left-width: 11px;
}
Setting the previous style sheet to the container of the text edits will turn all of them into this
Something quite similar to your desired look. Of course you have to prepare a good border image and better adjust the border dimensions but I think this could be of help.
If you want different styles for incoming and outgoing messages then you will have to
properly differentiate and select them in the style sheet. Check this for reference.

You need to modify Qt's source code for this.
I've done this last year.
You could set a background image (the bubble image ) for a frame.
If you r using Qt 4.8.6, locate qtextdocumentlayout.cpp, at line 402:
The default fill fillBackground implementation is
p->fillRect(rect, brush);
You could change to qDrawBorderPixmap instead to draw a bubble background.

You can use QBalloonTip which is an internal class defined in
QtDir/5.*/Src/qtbase/src/widgets/util/qsystemtrayicon_p.h
QBalloonTip inherits QWidget and it is implemented in qsystemtrayicon.cpp at the same directory. It has the following method to show a balloon tip:
void QBalloonTip::balloon(const QPoint& pos, int msecs, bool showArrow)
You can modify the source code of this class to have your desired balloon tip.

If you are interested in open source project that implements the same thing(I call it 'Bubble Chat'), you can search Telegram Desktop and Cutegram in Github.
They are both clients of Telegram or its variant implemented by Qt/Qml.
I think Cutegram is better.
Hope this tip will help you.

Related

Getting QTabWidget to lay flat

I have an application which uses a QTreeWidget next to a QTabWidget. On the frame that contains the two and the QTreeWidget I can set the properties:
frameShape : NoFrame --and-- frameShadow : Plain
This gives a nice flat look. But the QTabWidget does not have these properties and it has a shadow and is raised.
How do I get the QTabWidget to look flat?
Picture is attached.
You can use stylesheet to customize the look of the border.
Using stylesheet often resets some of the default/native style like the background so you will need to define it explicitely depending on your needs.
QTabWidget::pane { border: none; } // No border at all
QTabWidget::pane { border: 1px solid black; } // Simple black border
See the examples.
Based on your question and screenshot, your QTreeWidget is not actually flat, it has an inset style, while the QTabWidget has an outset. It's not very clear what you want to achieve exactly. But I fully agree with #ypnos in the comments, you seem to need a QStackWidget and not a QTabWidget.
I also think you should probably keep the native style, which will change depending on the OS and the user preferences. If you want to customize the look and feel of your application you generally need to customize all of it and make something consistent, not just a widget that does not please you.

Setting single stylesheet property in Qt

I'm trying to create vertical lines in a QTreeView; rather than painting over lines as suggested by some answers I am using a stylesheet to modify the right border of the cells in the treeview like so:
ui->tripsTreeView->setStyleSheet ("QTreeView::item:!last { border-right: 0.5px solid lightgray ;}");
Unfortunately this resets all other stylesheet properties on the treeview, making it unusable (white on white text, the expand triangle gets a blue background, custom background colours disappear, etc).
Questions:
Has someone managed to set a stylesheet for a single property in Qt?
Or found a way to extract the current applied stylesheet? I would then do a search-and-replace to add/set the proper border. Unfortunately ui->tripsTreeView->styleSheet() returns only an empty string (meaning it uses the deault stylesheet, but what the heck is the default stylesheet?)
When no stylesheet is set Qt uses a style which matches the style of the OS. When you try to change the stylesheet of even a single property the whole stylesheet of the control is replaced with a default one. I am not sure if the default stylesheet can be extracted. Probably a custom delegate with paint() function reimplemented can do the trick.

QT Tab bar's top highlight with stylesheet

I have a problem when trying to change the color of QTabBar's top line (blue line in the picture below).
Is this a separate part of tabBar (like scroller or tear) or its top border ? And how can I change its color with styleSheet and leave the other parts of tabBar unchanged?
P.S. : My tabBar::styleSheet returns an empty string, so I can't get current style and make changes in it.
If you're using a "system" style, you may not be able to change the color of the line (cause representation of UI elements is not handled by Qt but by the system).
You should define a complete style for QTabBar (and maybe QTabWidget too) that you can customize as you wish.
See the Qt Style Sheets Examples page.
Problem solved:
setStyleSheet("QTabBar::tab:selected { selection-background-color: red; }");

Modify button form in Qt

I'm new on Qt and I'm looking for some way to modify the form of a QPushButton, but I didn't find something on the web.
Is it possible and if so, how can I do this?
Thx
If you want to change how the QPushButton looks, you can use the Qt style sheets. If you want to put an image on the button, you can take advantage of the "background-image" property of the QPushButton
QPushButton
{
background-image: url("alpha.jpg");
}
You can change other properties like "border", "background-color", etc. Your question needs to be more specific as to what visual elements you need. Go through the documentation, it will help you.
One way to go about getting a different for the QPushButton is to make the necessary image available. Get the necessary image and make sure it has a transparent background. Use could use other attributes of QPushButton like, "background-color: transparent" and without any border - "border: none".
Hope it helps!

QWidget overrides Qscrollarea CSS

I'm trying to implement a complex UI in QT with a lot of customization.
This is what I'm trying to achieve (photoshop file)
This is my current screen, I just discovered that the original CSS sheet which was developed by someone had a global color setting for Qwidget, this color is being rendered in a lot of widgets, but the problem is that it's overiding the Scroll, which prevents me from changing the color on the left side (please see the blue dot)
The code for this is:
QWidget {
background-color: #1a1d21; /* software canvas background color */
border: 0px solid black;
}
QScrollArea {
background-color: #262a30;
border: 1px solid black;
}
I tried removing the color code in the CSS for QWidget which effected Qscrollarea and the color chosen was properly rendered, but some problems came up:
It removed color for a lot of widgets that I had and now it's all white, now I will have to specify individually which worries me, because it's not just time consuming considering the size of my application but also because it sometimes it doesn't work.
What also worries me is that I tried specifying background color to the specific widget and it didn't work, I've tried the placeholder object and class together and separated - QDockWidget / QDockWidget and also the real widget that is being called : QTabWidget / tabWidget. So I don't know whether it's because I'm doing something wrong in the code and not using still the correct object to change the color or if Qwidget is actually overriding the color (which makes me confused because I thought that child always overrides parent in CSS)
Note: I'm a designer and newbie in Qt and programming.
For every Qt widget you can provide an unique name. Then you can use that name to setup the desired widget style in the stylesheet (CSS)
If you're not using Qt Creator, widget name can be set using i.e. QWidget::setObjectName("scrollArea");

Resources