I would like to change the position of the lineEdit (or even a PushButton if it's not possible with the lineEdit) from my Qt application, according to the input given.
So let's say that I want the x position to be 150 pixels, then I would insert 150 into the lineEdit.
Is there any way to do this?
I've already tried this:
void DrawTest::on_lineEdit_returnPressed()
{
QString x = ui->lineEdit->text();
qDebug() << "x: " << x;
QString style = "QLineEdit {"
":" +ui->lineEdit->text()+ "px;"
"background-color: #FF00FF;"
"};";
qDebug() << "Style: " << style;
ui->lineEdit->setStyleSheet(style);
}
It depends on how the QLineEdit is initially positioned. Is it placed within a layout? If so, you won't be able to place it at an absolute position.
But if it does not belong to any layout, you can just use the move method:
ui->lineEdit->move(x, y);
Here's the docs.
Related
How can I get cursor shape when application minimized?
on hotkey I call:
qDebug() << "mouse (" << QCursor::pos().x() << "x" << QCursor::pos().y() << ")" << this->cursor().shape();
QCursor::pos() - is right, but cursor().shape() - always return "ArrowCursor" (even within the application).
How can I get real shape or cursor pixmap (Windows, MacOS)?
I don't think you can do this, at least not with Qt.
this->cursor() gives you a QCursor that was set on a certain QWidget using QWidget::setCursor. It's a simple accessor. It does not give you the current cursor being displayed (outside your program, window, not even outside the widget).
void QTextDocument::contentsChange(int position, int charsRemoved, int charsAdded) [signal]
This signal is emitted whenever the document's content changes; for example, when text is inserted or deleted, or when formatting is applied.
User can click cut/press delete/backspace or any other way and will remove text.
Problem is this signal emitted after text is removed. So I don't know which text was deleted.Now position and charsRemoved are of no use.
I want to find out deleted text of QPlainTextEdit. Is there any way to achieve this?
The trick with calling undo and redo suggested by Googie is nice, to make it even more efficient one can use a QTextCursor to extract the text instead of calling toPlainText:
void TextEdit::slotCheckRange(int pos, int removed, int added){
if(removed > 0){
undo();
QTextCursor c(textCursor());
c.setPosition(pos);
c.setPosition(pos + removed, QTextCursor::KeepAnchor);
qDebug() << "Removed: " << removed << " (" << c.selectedText() << ")";
redo();
}
if(added > 0){
QTextCursor c(textCursor());
c.setPosition(pos);
c.setPosition(pos + added, QTextCursor::KeepAnchor);
qDebug() << "Added: " << added << " (" << c.selectedText() << ")";
}
}
I see 2 possible solutions:
Store the contents of the document after every contents change, so in every next change you will have access to the previous contents and you will be able to extract the value using position and charsRemoved.
Pros: It's isolated mechanism and will not interfere with any other signals or slots.
Cons: It implies significant memory and CPU footprint (every text change causes full string copy).
(a better one in my opinion) In the slot function implementation use the undo() and redo() methods of the QPlainTextEdit to restore previous contents for the time of querying charsRemoved. Note, that calling undo() and redo() will not trigger the contentsChange() signal (I just tested it), so it's as simple as that.
Pros: Doesn't cause additional memory footprint. Not sure about the CPU footprint, but I think it's also better in that case.
Cons: This will only work with Undo/Redo mechanism enabled (which it is by default) and it also might affect any undo/redo code that you use or override (usually it's not the case).
To be clear, a sample code snipped for solution 2:
void MainWindow::textChanged(int pos, int rem, int add)
{
ui->plainTextEdit->undo();
qDebug() << ui->plainTextEdit->document()->toPlainText().mid(pos, rem); // <- text removed
ui->plainTextEdit->redo();
qDebug() << ui->plainTextEdit->document()->toPlainText().mid(pos, add); // <- text added
}
I have the following code (implemented in the mouseReleaseEvent) to detect when the user has selected lines of text:
QTextCursor cursor = this->textCursor();
int start = cursor.selectionStart();
int end = cursor.selectionEnd();
if(!cursor.hasSelection())
return; // No selection available
qWarning() << "start: " << start << " end: " << end << endl;
the problem is: I need the line numbers where the selection begins and ends. I've been struggling with blocks and solved nothing, can you please give me a clue?
It is possible, that it isn't the best solution, but it seems to work for me. The variable selectedLines will contain, how many lines are selected.
QTextCursor cursor = ui->plainTextEdit->textCursor();
int selectedLines = 0; //<--- this is it
if(!cursor.selection().isEmpty())
{
QString str = cursor.selection().toPlainText();
selectedLines = str.count("\n")+1;
}
I hope, that it will be helpful :)
I see easy way to use chain of 2 QTextCursor methods - setPosition and blockNumber.
QTextCursor cursor = this->textCursor();
int start = cursor.selectionStart();
int end = cursor.selectionEnd();
if(!cursor.hasSelection())
return; // No selection available
cursor.setPosition(start);
int firstLine = cursor.blockNumber();
cursor.setPosition(end, QTextCursor::KeepAnchor);
int lastLine = cursor.blockNumber();
qWarning() << "start: " << firstLine << " end: " << lastLine << endl;
UPD:
cursor.setPosition(start);
cursor.block().layout()->lineForTextPosition(start).lineNumber();
// or
cursor.block().layout()->lineAt(<relative pos from start of block>).lineNumber();
Set position to begin of selection. Get current block, get layout of block and use Qt API for getting line number. I doesn't know which line number returned is absolute for whole document or for layout. If only for layout, you need some additional process for calculate line numbers for previous blocks.
for (QTextBlock block = cursor.block(). previous(); block.isValid(); block = block.previous())
lines += block.lineCount();
I have a QTextEdit which act as "displayer" (editable to false). The text it displays is wordwrapped. Now I do wish to set the height of this textbox so that the text fits exactly (while also respecting a maximum height).
Basically the widget (in the same vertical layout) below the layout should get as much space as possible.
How can this be achieved most easily?
I found a pretty stable, easy solution using QFontMetrics!
from PyQt4 import QtGui
text = ("The answer is QFontMetrics\n."
"\n"
"The layout system messes with the width that QTextEdit thinks it\n"
"needs to be. Instead, let's ignore the GUI entirely by using\n"
"QFontMetrics. This can tell us the size of our text\n"
"given a certain font, regardless of the GUI it which that text will be displayed.")
app = QtGui.QApplication([])
textEdit = QtGui.QPlainTextEdit()
textEdit.setPlainText(text)
textEdit.setLineWrapMode(True) # not necessary, but proves the example
font = textEdit.document().defaultFont() # or another font if you change it
fontMetrics = QtGui.QFontMetrics(font) # a QFontMetrics based on our font
textSize = fontMetrics.size(0, text)
textWidth = textSize.width() + 30 # constant may need to be tweaked
textHeight = textSize.height() + 30 # constant may need to be tweaked
textEdit.setMinimumSize(textWidth, textHeight) # good if you want to insert this into a layout
textEdit.resize(textWidth, textHeight) # good if you want this to be standalone
textEdit.show()
app.exec_()
(Forgive me, I know your question is about C++, and I'm using Python, but in Qt they're pretty much the same thing anyway).
Unless there is something particular to the capabilities of a QTextEdit that you need, a QLabel with word wrap turned on will do exactly what you want.
Current size of the underlying text can be available via
QTextEdit::document()->size();
and I believe that using this we could resize the widget accordingly.
#include <QTextEdit>
#include <QApplication>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QTextEdit te ("blah blah blah blah blah blah blah blah blah blah blah blah");
te.show();
cout << te.document()->size().height() << endl;
cout << te.document()->size().width() << endl;
cout << te.size().height() << endl;
cout << te.size().width() << endl;
// and you can resize then how do you like, e.g. :
te.resize(te.document()->size().width(),
te.document()->size().height() + 10);
return a.exec();
}
In my case, I put my QLabel inside a QScrollArea. And if you are keen, you combine both and make your own widget.
Speaking of Python, I actually found .setFixedWidth( your_width_integer ) and .setFixedSize( your_width, your_height ) quite useful. Not sure if C has similar widget attributes.
message.Text() is a QString.
I want to remove some text.
The text can be:
Normal: "This is a text"
With a label: "<label1>something</label1>This is a text"
First, I find if the text has the label:
!message.Text().contains("<label1>", Qt::CaseInsensitive))
So, if it has, I want to remove the first part, to have a normal text "This is a text".
I tried this:
first=message.Text().indexOf("<label1>");
last=message.Text().lastIndexOf("</label1>");
message.Text().remove(first,last);
But I got Compiler Error C2663.
I also know that the message.Text().remove(QChar('<label1'), Qt::CaseInsensitive); is another way to do it. But in my case, the part between the label is unkwnow.
It can be <label1>something</label1> or <label1>oisdioadj</label> or <label1>7</label1>....
Any idea?
Regards.
Try the following:
#include <iostream>
using std::cout; using std::endl;
#include <QString>
int main()
{
QString message = "<label1>something</label1>This is a test";
const QString labelClose = "</label1>";
const int labelCloseSize = labelClose.size();
cout << "message: " << qPrintable(message) << endl;
const int closePosition = message.lastIndexOf(labelClose);
QString justText = message.remove(0, closePosition + labelCloseSize);
cout << "just text: " << qPrintable(justText) << endl;
}
My advice here: keep things simple in your code, it will help making things simple in your head.
It seems what you want to achieve is more related to strings, than to label.
I suggest you get the text from your label, then work on it independently, then associate it back to your label:
QString text = message.text();
/* Do whatever you need to do here with text */
message.setText(text);
Also, the error you're having is probably due to the fact that you try to modify directly message.text() which is a const reference: obviously you can't modify something that is const.
I believe what you try to achieve can be done using QString::replace(). You'll have to use regular expressions for that, so if you're not familiar with it, it might be difficult.