Hide or Crop Overlapping Text in Qlabel

Hide or crop overlapping text in QLabel?

Widgets in a layout are always managed not to overlap, so I just see no way that the textLabel could overlap valueLabel. Most likely your widgets are not managed by the layout, even if they were added to the layout. Perhaps the layout with labels is not a child of another layout, or is not set on a container widget.

You're not telling us something. A self-contained test case would be good to have.

If you want a label to elide the text by finishing it with "..." instead of abruptly cutting it off, the following elided style can be used.

// Usage:
/*
QApplication app;
app.setStyle(new ElidedStyle);
...
QWidget * w = new QLabel("Hello World!");
w->setProperty("elidedItemText", true);
*/

// Interface

class ElidedStyle : public QProxyStyle
{
public:
static QString elidedText(const QString & text, QPainter * painter, const QRect & rect);
virtual void drawItemText(
QPainter * painter, const QRect & rect, int flags, const QPalette & pal,
bool enabled, const QString & text, QPalette::ColorRole textRole = QPalette::NoRole) const Q_DECL_OVERRIDE;
};

// Implementation

QString ElidedStyle::elidedText(const QString & text, QPainter * painter, const QRect & rect)
{
QWidget * widget = dynamic_cast<QWidget*>(painter->device());
if (widget && widget->property("elidedItemText").toBool()) {
QFontMetrics fm(painter->font());
return fm.elidedText(text, Qt::ElideMiddle, rect.width());
}
return text;
}

void ElidedStyle::drawItemText(
QPainter * painter, const QRect & rect, int flags, const QPalette & pal,
bool enabled, const QString & text, QPalette::ColorRole textRole) const
{
QProxyStyle::drawItemText(painter, rect, flags, pal, enabled, elidedText(text, painter, rect), textRole);
}

How do I get a crop an image in a QLabel from it to be rounded?

Can be easily implemented as custom QWidget with painter.setClipPath(const QPainterPath&) in paintEvent().

////////////////////////// roundedlabel.h

#ifndef ROUNDEDLABEL_H
#define ROUNDEDLABEL_H

#include <QWidget>

class RoundedLabel : public QWidget
{
Q_OBJECT
public:
explicit RoundedLabel(QWidget *parent = nullptr);
void setPixmap(const QPixmap& pixmap);
void setBorderRadius(int value);
QSize sizeHint() const;

protected:
void paintEvent(QPaintEvent *event);
int mBorderRadius;
QPixmap mPixmap;
};

#endif // ROUNDEDLABEL_H

////////////////////////// roundedlabel.cpp

#include "roundedlabel.h"

#include <QPainter>
#include <QPainterPath>

RoundedLabel::RoundedLabel(QWidget *parent) : QWidget(parent), mBorderRadius(0)
{

}

void RoundedLabel::setPixmap(const QPixmap &pixmap)
{
mPixmap = pixmap;
updateGeometry();
update();
}

void RoundedLabel::setBorderRadius(int value)
{
mBorderRadius = value;
update();
}

void RoundedLabel::paintEvent(QPaintEvent *event)
{
if (mPixmap.isNull()) {
return;
}
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
QRect r = this->rect();
int radius = mBorderRadius;
QPainterPath clipPath;
clipPath.moveTo(radius, 0);
clipPath.arcTo(r.right() - radius, 0, radius, radius, 90, -90);
clipPath.arcTo(r.right() - radius, r.bottom() - radius, radius, radius, 0, -90);
clipPath.arcTo(r.left(), r.bottom() - radius, radius, radius, 270, -90);
clipPath.arcTo(r.left(), r.top(), radius, radius, 180, -90);
clipPath.closeSubpath();
painter.setClipPath(clipPath);
painter.drawPixmap(QPoint(0,0),mPixmap);
}

QSize RoundedLabel::sizeHint() const
{
return mPixmap.isNull() ? QSize(40,40) : mPixmap.size();
}

////////////////////////// main.cpp

#include <QApplication>
#include <QVBoxLayout>
#include "roundedlabel.h"

int main(int argc, char *argv[])
{
QApplication a(argc, argv);

QString image_path = ":/images/photo.png";

RoundedLabel* label = new RoundedLabel();
label->setPixmap(QPixmap(image_path).scaled(40,40));
label->setBorderRadius(5);

QWidget widget;
QVBoxLayout* layout = new QVBoxLayout();
layout->addWidget(label, 0, Qt::AlignCenter);
widget.setLayout(layout);
widget.setStyleSheet("background : rgb(42,45,49); border-radius : 2px; border : 2px; border-color : (90,92,95);");
widget.show();
widget.setGeometry(QRect(widget.pos(), QSize(200,100)));

return a.exec();
}

source

qt4.7: Can't see the text of QLabel derived class

Maybe you need to call the QLabel constructor from your PaintRect constructor?

Or maybe you need to call the parent's paintEvent from the PaintRect's paintEvent.

Qt application name placeholder

No, there isn't an existing mechanism to do that. Fortunately, you can implement your own.

To substitute text in controls, you can use a proxy style that replaces all occurences of "macros" that you specify.

To substitute text in window titles, you have to intercept the QEvent::WindowTitleChange.

To make such macros unique, you should wrap them with some control codes: here, US/RS. A complete example follows.

// https://github.com/KubaO/stackoverflown/tree/master/questions/text-wildcard-40235510
#include <QtWidgets>

constexpr auto US = QChar{0x1F};
constexpr auto RS = QChar{0x1E};

class SubstitutingStyle : public QProxyStyle
{
Q_OBJECT
QMap<QString, QString> substs;
public:
static QString _(QString str) {
str.prepend(US);
str.append(RS);
return str;
}
void add(const QString & from, const QString & to) {
substs.insert(_(from), to);
}
QString substituted(QString text) const {
for (auto it = substs.begin(); it != substs.end(); ++it)
text.replace(it.key(), it.value());
return text;
}
virtual void drawItemText(
QPainter * painter, const QRect & rect, int flags, const QPalette & pal,
bool enabled, const QString & text, QPalette::ColorRole textRole = QPalette::NoRole) const override;
};

void SubstitutingStyle::drawItemText(
QPainter * painter, const QRect & rect, int flags, const QPalette & pal,
bool enabled, const QString & text, QPalette::ColorRole textRole) const
{
QProxyStyle::drawItemText(painter, rect, flags, pal, enabled, substituted(text), textRole);
}

template <typename Base> class SubstitutingApp : public Base {
public:
using Base::Base;
bool notify(QObject * obj, QEvent * ev) override {
if (ev->type() == QEvent::WindowTitleChange) {
auto w = qobject_cast<QWidget*>(obj);
auto s = qobject_cast<SubstitutingStyle*>(this->style());
if (w && s) w->setWindowTitle(s->substituted(w->windowTitle()));
}
return Base::notify(obj, ev);
}
};

int main(int argc, char ** argv) {
SubstitutingApp<QApplication> app{argc, argv};
auto style = new SubstitutingStyle;
app.setApplicationVersion("0.0.1");
app.setStyle(style);
style->add("version", app.applicationVersion());

QLabel label{"My Version is: \x1Fversion\x1E"};
label.setWindowTitle("Foo \x1Fversion\x1E");
label.setMinimumSize(200, 100);
label.show();
return app.exec();
}
#include "main.moc"

See also: control text elision.

How to update a QLayout and get the new dimensions before returning?

I had this exact problem and could not find an answer anywhere on the Internet. Calling Layout.update(), Layout.activate(), or widget.adjustSize() (all suggested in various places) all did not work.

I had a widget with a vertical layout that I wanted to add a QLabel to and then immediately use the size of the QLabel.

The only thing that worked reliably was

layout->addWidget(myLabel);
myLabel->show();
size = myLabel->size();

It would seem that layouts will just not recalculate until you either return from a function and allow the Qt event loop to progress or manually call show() yourself.

How can I limit text box width of QLineEdit to display at most four characters?

If what you want is modify your QLineEdit width and fix it, use:

#setFixedWidth(int w)
MyLineEdit.setFixedWidth(120)

How to make a screenshot of the widget and paste it into the QGraphicsView?


Crop image in QWebEngineView

If you want to implement the crop of the QWebEngineView screenshot then you must use a QRubberBand that is on the focusProxy () of the QWebEngineView (it is the widget where the web page is rendered and receives the mouse event that is created after displaying the view)

from functools import cached_property
import sys

from PyQt5.QtCore import pyqtSignal, QEvent, QObject, QPoint, QRect, QSize, QUrl
from PyQt5.QtGui import QPixmap
from PyQt5.QtWidgets import QApplication, QLabel, QRubberBand
from PyQt5.QtWebEngineWidgets import QWebEngineView


class RubberBandManager(QObject):
pixmap_changed = pyqtSignal(QPixmap, name="pixmapChanged")

def __init__(self, widget):
super().__init__(widget)
self._origin = QPoint()
self._widget = widget

self.widget.installEventFilter(self)

@property
def widget(self):
return self._widget

@cached_property
def rubberband(self):
return QRubberBand(QRubberBand.Rectangle, self.widget)

def eventFilter(self, source, event):
if self.widget is source:
if event.type() == QEvent.MouseButtonPress:
self._origin = event.pos()
self.rubberband.setGeometry(QRect(self._origin, QSize()))
self.rubberband.show()
elif event.type() == QEvent.MouseMove:
self.rubberband.setGeometry(
QRect(self._origin, event.pos()).normalized()
)
elif event.type() == QEvent.MouseButtonRelease:
rect = self.rubberband.geometry()
pixmap = self.widget.grab(rect)
self.pixmap_changed.emit(pixmap)
self.rubberband.hide()
return super().eventFilter(source, event)


if __name__ == "__main__":
app = QApplication(sys.argv)
view = QWebEngineView()
view.load(
QUrl(
"https://www.google.com/maps/@36.797966,-97.1413048,3464a,35y,0.92h/data=!3m1!1e3"
)
)
view.show()
rubberband_manager = RubberBandManager(view.focusProxy())

label = QLabel()
label.hide()

def on_pixmap_changed(pixmap):
label.setPixmap(pixmap)
label.adjustSize()
label.show()

rubberband_manager.pixmap_changed.connect(on_pixmap_changed)

ret = app.exec()
sys.exit(ret)

Show an Image in QGraphicsView

To display an image then you must use a QGraphicsPixmapItem where you load a QPixmap.

import sys

from PyQt5.QtCore import Qt
from PyQt5.QtGui import QPixmap, QPainter, QPalette
from PyQt5.QtWidgets import (
QApplication,
QGraphicsView,
QGraphicsScene,
QGraphicsPixmapItem,
)


class ImageViewer(QGraphicsView):
def __init__(self, parent=None):
super().__init__(parent)
self.setRenderHints(QPainter.Antialiasing | QPainter.SmoothPixmapTransform)
self.setAlignment(Qt.AlignCenter)
self.setBackgroundRole(QPalette.Dark)

scene = QGraphicsScene()
self.setScene(scene)

self._pixmap_item = QGraphicsPixmapItem()
scene.addItem(self._pixmap_item)

def load_pixmap(self, pixmap):
self._pixmap_item.setPixmap(pixmap)
self.fitToWindow()

def fitToWindow(self):
self.fitInView(self.sceneRect(), Qt.KeepAspectRatio)

def resizeEvent(self, event):
super().resizeEvent(event)
self.fitToWindow()


if __name__ == "__main__":
app = QApplication(sys.argv)

view = ImageViewer()
view.resize(640, 480)
view.show()

pixmap = QPixmap("image.jpg")
view.load_pixmap(pixmap)

ret = app.exec()
sys.exit(ret)

The previous widget is used to load an image from a file: pixmap = QPixmap("/path/of/image") or use the QPixmap provided by pixmap_changed signal of RubberBandManager.



Related Topics



Leave a reply



Submit