QPlainTextEdit force redraw - qt

I'd like to force a redraw over a QPlainTextEdit widget, because my highlighting rules changed. However, all lines and blocks aren't redrawn, respecting the new rules.
This is true because if I modify a line, the correct highlighting is applied, and I am happy. But I cannot force-modify each block to see any change!
Is there a way to force a redraw? I tried update() and similars, but nothing seems to work.
Thanks!

QPlainTextEdit inherits QAbstractScrollArea, so its content is located in viewport widget. Try this:
text_edit->viewport()->update();

You have to call QSyntaxHighlighter::rehighlight() to apply the new highlighting rules to the whole document.

You can try:
text_edit->repaint();

In my case simply calling rehighlight don't update view. In my case i want update highlight when cursor moves so:
void MyHighlighter::onSelectionChanged(int start, int end)
{
_visibleCursor.setPosition(end);
document()->documentLayout()->updateBlock(_visibleCursor.block());
rehighlightBlock(_visibleCursor.block());
}

Related

How to display a QLabel under another QLabel?

I have some QLabels in a QWindow. They might have some space in common. I want to know how can I change label's depth. In default situation the label which defined later is on the previews ones.
You can define an indent for each widget and call raise_ function in sort of their indent.
for label in labels:
label.raise_()
you should use raise, like :
labelname.raise_()
All widgets have methods for this.
widget.stackUnder(another_widget) #relative postition
widget.lower() # send to the bottom
widget.raise_() # send to the top
See documentation on QWidget

Stop Invisible Label from taking up space

Is there a way to stop a label control that is not visible from taking up space on a form?
server side:
label.Attributes["style"] = "display:none";
or
label.Visible = false;
or, client-side (css):
#label-id { display: none; }
Set it's visibility to hidden through CSS. Or set it through the code behind to false. From the code behind a false setting should cause it to not be rendered at all.
Optionally, replace the label with a literal control and only emit something to it when you need to.
2 good answers already, so just a couple of notes:
Using Visible=false at the server-side is usually better since that will not output any HTML at all, as opposed to CSS which will output it but just hide it. Unless of course you need it there so you can unhide client-side.
The label itself usually doesn't add any space, it is the white-space before/after it that might, so yet another option (if you work in HTML source view 99% of the time like I do) is to remove any white-space before/after the control. Not as robust as the other options since it could be easy to get that white-space back by mistake (especially if the IDE does it for you while working in design view). Just thought I'd mention it, since this can be good to know if you want the label VISIBLE but don't want the "extra space".

Flex TextArea scroll down

I have a TextArea that shows the conversation from selected chat room. For valueCommit event I use: verticalScrollPosition = maxVerticalScrollPosition; And it works fine scrolling text to the bottom. However in one case it doesn't work as expected. There's verylittle text, so TextArea has no scrollbar and then I put a lot of text and a scrollbar is necessary. The text is scrolled almost to the bottom (still a few lines need to be scrolled down). I am pretty sure it gets maxVerticalScrollPosition as if there was no scrollbar. So the question is how can I wait with updating verticalScrollPosition with respect to TextArea's new size (that is now with a scrollbar). I tried calling validateSize and other methods that start with 'validate' but unfortunately with no luck. I also tried the old trick of putting caret at the end of text. So the TextArea's scrollbar makes a difference when getting maxVerticalScrollPosition and I need to update verticalScrollPosition once all measurements are done.
I forgot to mention. I use htmlText.
In the comments of the answer you accepted you mentioned a more elegant solution. Yeah, a timer probably isn't the best option -- you have eventListener cleanup if you remove the component from the stage; if you use the component more than once, you have another timer instance; etc., etc.
If you don't have a lot of post-commit-property actions, the quickest solution would be a call later on the setter of text or htmlText
override public function set text(value:String):void
{
super.text = value;
callLater( scrollToEndAfterTextCommitted );
}
protected function scrollToEndAfterTextCommitted():void
{
this.verticalScrollPosition = this.maxVerticalScrollPosition;
}
I hope that helps.
Best of luck!
Assuming the issue is fixed after you add additional text again, you could probably get by using a Timer, or a call to setTimeout and have the verticalScrollPosition = maxVerticalScrollPosition called a fraction of a second later and see if that fixes it.

How to program scrollbar to jump to bottom/top in case of change in QPlainTextEdit or QTextEdit area?

How to program scrollbar to jump to bottom/top in case of change in QPlainTextEdit or QTextEdit area?
It looks like it doesn't have any controlling function.
QTextEdit and QPlainTextEdit are both inherited from QAbstractScrollArea. The QAbstractScrollArea object provides access to the scrollbar through the verticalScrollBar() method.
Thus, to jump to the top:
ui.textEdit->verticalScrollBar()->setValue(0);
And to jump to the bottom:
ui.textEdit->verticalScrollBar()->setValue(ui.textEdit->verticalScrollBar()->maximum());
This should work for both QTextEdit and QPlainTextEdit.
You can use the 'ensureCursorVisible' method:
void QTextEdit::ensureCursorVisible ()
Ensures that the cursor is visible by scrolling the text edit if necessary.
This is not a slot, though, so you can't connect it to any signal -- you'll have to create something yourself that you can connect to the void textChanged() signal.
Disclaimer: I may have misunderstood your question -- I assume you want to scroll down when some text is appended to the text.
When a text edit control is resized, QWidget::resizeEvent is called. You just have to override this function in your subclass, and call verticalScrollBar -> setValue (verticalScrollBar -> minimum()) (or maximum()).
I have done in Pyqt.
self.scrollArea.verticalScrollBar().rangeChanged.connect(self.change_scroll)
--------
#pyqtSlot(int, int)
def change_scroll(self, min, max):
print("cambio", min, max)
self.scrollArea.verticalScrollBar().setSliderPosition(max)
Here I am posting my Solution as above solution dint work in my case.
I want to get the cursor at the beginning of QTextbrowser.
By using QTextEdit::setTextCursor, you can move the visible cursor where you want:
// Go to beginning
QTextCursor textCursor = ui->textBrowser->textCursor();
textCursor.movePosition(QTextCursor::Start, QTextCursor::MoveAnchor,1);
ui->textBrowser->setTextCursor(textCursor);
Hope, it will help to some one and save their precious time.
I am using QTextEdit and textEdit.verticalScrollBar().setValue(0) doesn't work for me.
In my case, textEdit.moveCursor(QTextCursor.Start) can scroll to the top.

how to code NSButton to look just like image

Using code (not the Interface builder) I need to create an NSButton that looks like an image. Specifically I want to use NSImageNameStopProgressFreestandingTemplate and I need it not to look like button but to look like the image. This means:
1. No 'button down' look
2. No border, no any visibility of the button
Thanks.
I know this response is a bit late, but you could try this, given thisButton:
[thisButton setImage:[NSImage imageNamed:NSImageNameStopProgressFreestandingTemplate]];
[thisButton setImagePosition:NSImageOnly];
[thisButton setBordered:NO];
That last line is the key bit: removing the button border effectively strips it of its bezel, leaving only the image to click on. (BTW, I haven't tried the above code specifically, so you may need to throw in a couple of other tweaks, such as setting the imageScaling or buttonType, to get it to work best.)
One final note: If you're using a template image (as you said you would), Cocoa will automatically display it with a slight dark-grey gradient; when the button is clicked, it will momentarily darken to solid black. This is an automatic "'button down' look" you didn't want; however, it is very subtle, and is a good indicator that the button worked. If you don't want this to happen, you could get an instance of the desired image and [stopImage setTemplate:NO]; on it.
Disable isBordered
let button = NSButton(
image: NSImage(named: NSImage.Name("plus"))!,
target: self,
action: #selector(onButtonPress)
)
button.isBordered = false
If you don't want to use a templated but want the push down highlight anyways, you can also use the following setup for an NSButton:
let imageButton = NSButton()
imageButton.image = NSImage(named: "MyImage")!
imageButton.bezelStyle = .shadowlessSquare
imageButton.isBordered = false
imageButton.imagePosition = .imageOnly
The important thing to make the highlight work on any image is to set bezelStyle to shadowlessSquare.
I know this behavior wasn't requested in the question, but it might be useful for others.

Resources