Remove/delete/replace selected text in QGraphicsTextItem - qt

I would like to delete the selected text inside a QGraphicsTextItem.
I have been searching all the classes it uses - like QTextCursor, QTextDocument... I can't find anything to remove text, except the clear() function of the QTextDocument which removes everything...
How can I remove the selection ?
QTextCursor _cursor = textCursor();
if(_cursor.hasSelection())
?
Alternatively (since I need this for a custom paste command), how can I replace the selection with an existing text or html ?
QClipboard* _clipboard = QApplication::clipboard();
const QMimeData* _mimeData = _clipboard->mimeData();
if (_mimeData->hasHtml())
{
QTextCursor _cursor = textCursor();
if(_cursor.hasSelection())
?
_cursor.insertHtml(_mimeData->html());
}

Is not working QTextCursor::removeSelectedText()?
In the next example, we have at the beginning the text QGraphics Text Item 1, but as you will see, we can get the QTextDocument and also the QTextCursor for that document and insert some words.
After that, we move the cursor to the next word. Finally, we select the word under the cursor (Text) and remove it from our QGraphicsTextItem.
#include <QApplication>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QGraphicsTextItem>
#include <QTextCursor>
#include <QTextDocument>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QGraphicsScene scene;
QGraphicsView view(&scene);
QGraphicsTextItem* item_1 = new QGraphicsTextItem("QGraphics Text Item 1");
item_1->setTextInteractionFlags(Qt::TextEditorInteraction);
QTextDocument* doc = item_1->document();
scene.addItem(item_1);
QTextCursor cursor(doc);
cursor.beginEditBlock();
cursor.insertText(" Hello ");
cursor.insertText(" World ");
cursor.endEditBlock();
cursor.movePosition(QTextCursor::NextWord);
cursor.select(QTextCursor::WordUnderCursor);
cursor.removeSelectedText();
view.setFixedSize(640, 480);
view.show();
return a.exec();
}

Related

Getting the value of a QLabel with an accessible name using UI Automation

I'm trying to write an UI test (using Windows UI Automation) for an application that uses a QLabel to show an output to a user.
I create the label like this:
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QMainWindow w;
w.setWindowTitle("MyWindowTitle");
auto centralWidget = new QWidget(&w);
centralWidget->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
QVBoxLayout layout(centralWidget);
auto interrestingLabel = new QLabel(centralWidget);
QString valueCalculatedByApp = "1337";
interrestingLabel->setText(valueCalculatedByApp);
//interrestingLabel->setAccessibleName("MyAccessibleName");
layout.addWidget(interrestingLabel);
auto uninterrestingLabel = new QLabel(centralWidget);
uninterrestingLabel->setText("uninterrestingText");
layout.addWidget(uninterrestingLabel);
w.setCentralWidget(centralWidget);
w.show();
return a.exec();
}
Inspect.exe now shows the value "1337" as name of the widget:
Without accessible name
The problem with this would be that my UI test would need to figure out which one is the correct label.
If I uncomment setAccessibleName line, the widget is now identifiable, but I the text is no longer in visible in the properties.
With accessible name
Is there a way to read the text of a QLabel with an accessible name, or is there another way to make the QLabel identifieable while still being able to read the text?
I found a workaround:
Instead of a QLabel I use a QLineEdit. I set enabled to false so it is not selectable or editable (Like a QLabel) and use QSS to make it look like a QLabel:
#include <QApplication>
#include <QLabel>
#include <QLineEdit>
#include <QMainWindow>
#include <QSizePolicy>
#include <QVBoxLayout>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
a.setAttribute(Qt::AA_NativeWindows);
QMainWindow w;
w.setWindowTitle("MyWindowTitle");
auto centralWidget = new QWidget(&w);
centralWidget->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
QVBoxLayout layout(centralWidget);
auto interrestingLabel = new QLineEdit(centralWidget);
QString valueCalculatedByApp = "1337";
interrestingLabel->setText(valueCalculatedByApp);
interrestingLabel->setAccessibleName("MyAccessibleName");
interrestingLabel->setEnabled(false);
interrestingLabel->setStyleSheet(
"border-style: none;"
"color: black;"
"background:transparent"
);
layout.addWidget(interrestingLabel);
auto uninterrestingLabel = new QLabel(centralWidget);
uninterrestingLabel->setText("uninterrestingText");
layout.addWidget(uninterrestingLabel);
w.setCentralWidget(centralWidget);
w.show();
return a.exec();
}

Can we include and show some others widgets in a QVideoWidget? [duplicate]

everyone! I try to set a click property to a QMediaPlayer Element, but I can not find the mode to make it, and if I try to put a button in front to Video, the button puts behind to video, even with
button->raise();
videoWidget->lower();
And If I put a Button to fullscreen the screen turns in black and don't shows the video
this id the code of the video player
QMediaPlayer *player = new QMediaPlayer(this);
QVideoWidget *vw = new QVideoWidget(this);
QMediaPlaylist *PlayList = new QMediaPlaylist(this);
PlayList->addMedia(QUrl::fromLocalFile("/home/user/Videos/video.mp4"));
PlayList->setPlaybackMode(QMediaPlaylist::Loop);
QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(vw);
player->setVideoOutput(vw);
player->setPlaylist(PlayList);
vw->setGeometry(0,0,800,480);
vw->show();
player->play();
One possible solution is to create a widget where the QVideoWidget is placed through a layout, the button is also added and we change the position through the resizeEvent() event.
#include <QApplication>
#include <QMediaPlayer>
#include <QMediaPlaylist>
#include <QPushButton>
#include <QUrl>
#include <QVBoxLayout>
#include <QVideoWidget>
#include <QDebug>
class VideoWidgetButton: public QWidget{
QPushButton *btn;
QVideoWidget *vw;
QMediaPlayer *player;
public:
VideoWidgetButton(QWidget *parent=Q_NULLPTR):QWidget(parent){
setLayout(new QVBoxLayout);
layout()->setContentsMargins(0, 0, 0, 0);
vw = new QVideoWidget(this);
btn = new QPushButton(this);
btn->setIcon(QIcon(":/icons/tux.jpeg"));
btn->resize(QSize(128, 128));
btn->setIconSize(QSize(128, 128));
connect(btn, &QPushButton::clicked, [](){
qDebug()<<"clicked";
});
layout()->addWidget(vw);
player = new QMediaPlayer(this);
player->setVideoOutput(vw);
QMediaPlaylist *playList = new QMediaPlaylist(this);
playList->addMedia(QUrl("qrc:/video/SampleVideo_1280x720_1mb.mp4"));
playList->setPlaybackMode(QMediaPlaylist::Loop);
player->setPlaylist(playList);
player->play();
}
protected:
void resizeEvent(QResizeEvent *ev){
btn->move(rect().bottomRight()-btn->rect().bottomRight());
return QWidget::resizeEvent(ev);
}
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
VideoWidgetButton w;
w.resize(640, 480);
w.show();
return a.exec();
}
The complete example can be found in the following link.

Undesirable text overlapping

When I edit the QTableView the old text is not cleared and so the new text overlaps it. How can I avoid this behaviour?
The code:
#include <QApplication>
#include <QtSql>
#include <QtGui>
#include <QTableView>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QSqlDatabase db1 = QSqlDatabase::addDatabase("QSQLITE");
db1.setDatabaseName(":memory:");
db1.open();
QSqlQuery("CREATE TABLE test (a integer primary key, s text)");
QSqlQuery("INSERT INTO test VALUES (1, 'aaa');");
QSqlTableModel *model = new QSqlTableModel(0, db1);
model->setTable("test");
model->select();
QTableView *view = new QTableView;
view->setModel(model);
view->show();
return a.exec();
}
I have simular issue with dynamic QLabel.
When label text is updated new text was overlaped with old one. The problem was related to transparent background color.
As you find out the solution for you is to use such stylesheet QTableView::item {}
Complete Code:
view->setStyleSheet("QTableView::item {}");

Displaying database values with radio button selection in Qt?

I want to show some database row values with radio button selection in Qt GUI. How this can be accomplished?. This could be done using foreach loop I guess. I have studied a bit about the following classes :
1) QMainWindow
2) QSqlTableModel
3) QTableWidget.
But which one satisfies my requirement? I am not able to implement it, please guide me. Thanks in advance.
I have implemented upto this in my source file-
main.cpp:
#include <QtGui/QApplication>
#include <QtSql>
#include <QTableWidget>
#include <QMessageBox>
#include "mainwindow.h"
#include <QRadioButton>
#include <QVBoxLayout>
#include <QGroupBox>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QTableWidget* table = new QTableWidget();
table->setWindowTitle("Connect to Mysql Database Example");
QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");
db.setHostName("localhost");
db.setDatabaseName("guests");
db.setUserName("sri");
db.setPassword("******");
if (!db.open())
{
QMessageBox::critical(0, QObject::tr("Database Error"),
db.lastError().text());
}
QSqlQuery query("SELECT * FROM new_members");
table->setColumnCount(query.record().count());
table->setRowCount(query.size());
int index=0;
while (query.next())
{
table->setItem(index,0,new QTableWidgetItem(query.value(0).toString()));
table->setItem(index,1,new QTableWidgetItem(query.value(1).toString()));
index++;
}
// This is sample radiobutton from QGroupBox class. Like this I need to implement the values from DB in with radio button selections for each value
QMainWindow *window = new QMainWindow();
window->setWindowTitle(QString::fromUtf8("QGroupBox"));
window->resize(400, 400);
QGroupBox *groupBox = new QGroupBox("Radio Buttons");
QRadioButton *radio1 = new QRadioButton("Radio button 1");
radio1->setChecked(true);
QVBoxLayout *vbox = new QVBoxLayout;
vbox->addWidget(radio1);
groupBox->setLayout(vbox);
window->setCentralWidget(groupBox);
window->show();
table->show();
//MainWindow w; w.show();
return a.exec();
}
Use a QSqlTableModel to drive a QTableView, you will need a custom QStyledItemDelegate to draw the QRadioButton (yes I said draw, and not create), and create an editor widget (of course that really will be a QRadioButton).
This is quite a big job, so you will need to read the above class' docs to reimplement the bits you need. Start with the MVC documents.

'Magical' QTextEdit size

Here is an equivalent extracted code:
#include <QApplication>
#include <QWidget>
#include <QVBoxLayout>
#include <QTextBrowser>
#include <QTextEdit>
class ChatMessageEdit : public QTextEdit {
public:
ChatMessageEdit(QWidget* parent) : QTextEdit(parent) { }
virtual QSize sizeHint() const { return QSize(0, 25); }
};
int main(int argc, char** argv) {
QApplication app(argc, argv);
QWidget* widget = new QWidget;
QVBoxLayout* layout = new QVBoxLayout;
QTextBrowser* log = new QTextBrowser(widget);
layout->addWidget(log, 1);
ChatMessageEdit* editor = new ChatMessageEdit(widget);
editor->setMinimumHeight(editor->sizeHint().height()); // empty
layout->addWidget(editor);
widget->setLayout(layout);
widget->show();
return app.exec();
}
The minimum size for editor is 25px, and so is it's minimal size. But by some strange reason it is created with a size about 100px that is always preferred to my size hint. Everything other is working as expected: expanding (size hint isn't really fixed in my application), shrinking etc. I tried changing size policy, but with abolutely no result.
This was the minumumSizeHint() method. I overloaded it to return sizeHint(), and everything is working as expected now.
You are also overlooking how layouts work. Please read up here on why your sizes are not being respected in a layout.

Resources