Skip to content
  • 0 Votes
    4 Posts
    43 Views
    JonBJ

    @Khamza
    First to answer your question. Your new code delays the update till after the text edit has been shown. In that sense it is similar to the QTimer approach. For unknown reason you are claiming the code does not work correctly until after the text edit has been shown.

    There are cases in Qt which this is necessary. In particular sizes of widgets are not calculated till they are actually shown, so code which requires to know a size is often delayed in one of the above two fashions.

    HOWEVER I was never convinced by your assertion "The function itself is called but neither text is inserted nor block format changed:". While I could believe that possibly an operation on textCursor() might require the text edit to be shown I never thought that insertPlainText() for sure would depend on that. It should be callable any time, including e.g. during construction.

    I have now had time to create a minimal repro. Here are the 3 files:

    #include "passwordshowarea.h" #include <QApplication> int main(int argc, char *argv[]) { QApplication a(argc, argv); PasswordShowArea w; w.show(); return a.exec(); } #ifndef PASSWORDSHOWAREA_H #define PASSWORDSHOWAREA_H #include <QTextEdit> class PasswordShowArea : public QTextEdit { Q_OBJECT public: PasswordShowArea(QWidget *parent = nullptr); private: void init(); void updateBlockFormat(); }; #endif // PASSWORDSHOWAREA_H #include <QAbstractTextDocumentLayout> #include <QTimer> #include "passwordshowarea.h" PasswordShowArea::PasswordShowArea(QWidget *parent) : QTextEdit(parent) { init(); //doesn't work updateBlockFormat(); // works - gpt4 suggest // QTimer::singleShot(0, this, &PasswordShowArea::updateBlockFormat); } void PasswordShowArea::init() { // QObject::connect(document()->documentLayout(), &QAbstractTextDocumentLayout::update, // this, &PasswordShowArea::updatePasswordShowArea); setTextColor(palette().color(QPalette::Text)); } void PasswordShowArea::updateBlockFormat() { insertPlainText("Some text"); QTextBlockFormat fmt = textCursor().blockFormat(); fmt.setTextIndent(20); fmt.setLineHeight(fontMetrics().height() * 2, QTextBlockFormat::LineDistanceHeight); fmt.setBackground(Qt::red); textCursor().mergeBlockFormat(fmt); }

    I have made couple of tiny tweaks where I did not have all of your code. I added fmt.setBackground(Qt::red); so that we had something to see. And here is what I get:

    Screenshot 2024-12-21 093554.png

    You can see that not only do I get the inserted text but I do also get the QTextBlockFormat changes. Identical if I change it to only call updateBlockFormat() on the delayed timer. Ubuntu 24.04, Qt 6.4.2.

    Sooo.... I suggest you try just this code.

  • 0 Votes
    4 Posts
    74 Views
    JonBJ

    @Khamza
    You are not supposed to just call paintEvent() from somewhere else, it's designed to be called during actual painting. If you override a base paintEvent() you can (and should) indeed call the base implementation from there.

  • 0 Votes
    7 Posts
    168 Views
    SGaistS

    Hi,

    KDE's Konsole also supports Windows, it might be easier to integrate it in your project.

  • 0 Votes
    5 Posts
    240 Views
    Pl45m4P

    @Axel-Spoerl said in QWidget Drag And Drop inside Layout. Is this a good way?:

    I have troubles to imagine what you mean by that. Colors aside, a widget is typically a rectangle. If I want to indicate a potential landing spot, I'd rather use a rectangle, than a line.

    I think @StudentScripter means the same behavior you see when adding widgets to a layout in QtDesigner.

    A "line" can be a thin rectangle :)

    You also see a rectangle when dragging QDockWidgets around showing the valid DockAreas.

    Maybe check the source code of QtCreator's Designer or QMainWindows dockarea.

  • 0 Votes
    5 Posts
    316 Views
    Pl45m4P

    Solved.

    For further readers:
    I've added a check to the child widget whether a user interaction happens within its drawn borders (a closed QPainterPath).
    If so, I consume the event and continue from there, if not, I ignore the event and pass it to the parent widget, i.e. the actual MyWidget, so that the overlaying child widget has some transparency for my defined events (some key and mouse interaction).

    Pretty easy if I think about it now.
    The idea of having some kind of a donut shaped widget (yellow part in my sketch), which does not occupy the center of its parent widget was stuck in my head way too long :))

  • 0 Votes
    8 Posts
    361 Views
    Pl45m4P

    @SiGa

    As @SimonSchroeder said above, if you were using layouts properly, there's almost no way that things overlap, when resizing the main widget. Only free floating widgets, which are not part of any layout might do.

  • 0 Votes
    18 Posts
    1k Views
    C

    @Joe-von-Habsburg My example recast with a changing background:

    // widget.h #ifndef WIDGET_H #define WIDGET_H #include <QWidget> class Widget : public QWidget { Q_OBJECT public: Widget(QWidget *parent = nullptr); ~Widget(); // QWidget interface protected: void mousePressEvent(QMouseEvent *event); void mouseReleaseEvent(QMouseEvent *event); void paintEvent(QPaintEvent *event); private slots: void setBackground(); private: QImage mBackground; QPointF mFrom; QPointF mTo; }; #endif // WIDGET_H // widget.cpp #include "widget.h" #include <QPaintEvent> #include <QPainter> #include <QLinearGradient> #include <QRandomGenerator> #include <QTimer> #include <QDebug> Widget::Widget(QWidget *parent) : QWidget(parent) , mBackground(500, 500, QImage::Format_RGB32) { setBackground(); QTimer *t = new QTimer(this); connect(t, &QTimer::timeout, this, &Widget::setBackground); t->start(1000); } Widget::~Widget() { } void Widget::mousePressEvent(QMouseEvent *event) { mFrom = event->position(); mTo = mFrom; } void Widget::mouseReleaseEvent(QMouseEvent *event) { mTo = event->position(); update(); } void Widget::paintEvent(QPaintEvent *event) { QPainter p(this); p.drawImage(event->rect(), mBackground); if (mFrom != mTo) { QPen pen(Qt::red); pen.setWidth(3); p.setPen(pen); p.drawLine(mFrom, mTo); } p.end(); } void Widget::setBackground() { QPainter p(&mBackground); const QRectF rectf(mBackground.rect()); QLinearGradient grad(rectf.topLeft(), rectf.bottomRight()); grad.setColorAt(0, QColor::fromRgb(QRandomGenerator::global()->generate())); grad.setColorAt(1, QColor::fromRgb(QRandomGenerator::global()->generate())); p.fillRect(mBackground.rect(), QBrush(grad)); p.end(); update(); }
  • QWidget control

    Solved General and Desktop
    6
    0 Votes
    6 Posts
    286 Views
    JonBJ

    @dan1973 said in QWidget control:

    b1->resize(this->size());

    I wouldn't even bother doing this in the constructor --- did you qDebug() << this->size() there like I suggested? But up to you, I guess it does no harm, it will get overwritten by call to Widget::resizeEvent() as soon as shown, I think.

  • 0 Votes
    2 Posts
    402 Views
    C

    @Hai-Anh-Luu Welcome to the forum.

    Until the widget is displayed its size, and the size of any child widget in a layout, is unknown. In the widget class constructor^^ the widget is not yet shown so you get either the size hint from the widget concerned or some other value.

    ^^ That is when executing this line window = NewGrid()

    One way to see the size that is initially allocated is to do so in a slot connected to a zero-length (or very short) single-shot QTimer. This will fire when the event loop is reached, after the UI is shown. That is when app.exec() is running.

  • 0 Votes
    9 Posts
    1k Views
    S

    @Pl45m4 said in Custom Widget not showing in layout:

    always returning QSize(width(), height()); doesn't feel like the best solution ;-)

    I guess that QPushButton uses the actual text displayed (plus some padding) to calculate the size hint. QFontMetrics might help here.

  • 0 Votes
    5 Posts
    932 Views
    A

    @SGaist Thanks for your suggestion. I will try to implement things with QtQuick.

  • 0 Votes
    6 Posts
    602 Views
    Christian EhrlicherC

    @Pl45m4 said in Custom widget using and extending Qt's pImpl:

    It was just about the naming?!
    Is this the way? :)

    I would say yes.

  • 0 Votes
    3 Posts
    799 Views
    johngodJ

    @julienchz
    Hi
    I have created some opengl tutorials check here: https://bitbucket.org/joaodeusmorgado/opengltutorials/src/master/
    I am using QOpenGLWidget, but I use mostly raw opengl, you could easily create a abstract render class, and then reuse it to QOpenGLWidget, or any other frame work of your choice render class.
    Hope it helps

  • 0 Votes
    6 Posts
    517 Views
    P

    @JonB
    @JoeCFD

    OK found that Wayland just doesn't allow to windows to move themselves.

    Not a necessary feature for me and can't solve the black screen problem when logging with Xorg.
    Will just ask gnome to center new windows with tweaks.

    Closing the topic.

    Thanks to both you.

  • 0 Votes
    11 Posts
    957 Views
    Christian EhrlicherC

    Not read the whole thread but maybe this is of interest: https://wiki.qt.io/TaskTree

  • 0 Votes
    6 Posts
    511 Views
    Pl45m4P

    @RudrakshS

    So you dont want to provide any more information?
    e.g.

    what layout, if any? move which widgets from where to where? how does the destination look like? empty widget or any other stuff in it?

    You dont have to apologize, but YOU have an issue with your code, not us :)
    If you dont show what you've done, one can only guess.

    If it is, what I think it is, then you are missing a layout somewhere or make any unallowed "moves".

  • 0 Votes
    7 Posts
    1k Views
    S

    Well, Qt has both a QMenu and a QMenuItem. Only the QMenuItem is supposed to trigger actions. The QMenu itself only has QMenuItems and submenus. So, its action is already defined.

    Usually, the QMenuItems have QActions associated with it. For the QMenu::triggered signal the documentation states:

    This signal is emitted when an action in this menu is triggered.

    To me this reads that you have several entries inside the QMenu and one of these entries triggers an action. This is also why this signal contains the QAction as a parameter. My understanding would mean that clicking on the QMenu itself does not emit a triggered signal, but only clicking on a QMenuItem does.

  • 0 Votes
    2 Posts
    2k Views
    C

    From the Qt documentation (qt6), QTabWidget::setCornerWidget: says:

    Note: Corner widgets are designed for North and South tab positions; other orientations are known to not work properly.

    That means they do work, but are messy to and inconvenient to use.

    Here's a way to use QTabWidget corner widget on the side:

    As already noted in the question, setting a corner widget while tabs position is West or East, causes a small gap before the tabs without anything appearing there.

    But if you set QTabWidget's corner widget minimum size, it will appear, which solves a problem but causes another, because now I need to calculate that size myself, or make room for my corner widget.

    Here's an MRE that I used to try and figure how to get that empty corner size:

    QTabWidget *t = new QTabWidget(); //I needed the stacked widget so I can use its geometry to calculate the empty corner size QStackedWidget *stack_widget = t->findChild<QStackedWidget*>("qt_tabwidget_stackedwidget"); t->setMinimumSize(800,600); t->addTab(new QWidget(),"Tab1"); t->addTab(new QWidget(),"Tab2"); t->addTab(new QWidget(),"Tab3"); t->addTab(new QWidget(),"Tab4"); t->setTabPosition(QTabWidget::TabPosition::West); QToolButton *button1 = new QToolButton(); button1->setIcon(QIcon(":/icons/collapse.png")); t->setCornerWidget(button1,Qt::TopLeftCorner); t->show(); //width is equal to where the stack widget starts (x coordinate) //height is equal to where the tab bar starts (y coordinate) //I subtracted 1 from stackwidget's x because it simply looked better t->cornerWidget(Qt::TopLeftCorner)->setMinimumSize(stack_widget->geometry().x()-1, t->tabBar()->geometry().y()); //checking related widgets geometries /*qDebug()<<"cornerWidget geo"<<t->cornerWidget(Qt::TopLeftCorner)->geometry(); qDebug()<<"tabBar rect"<<t->tabBar()->tabRect(0); qDebug()<<"tabBar geo"<<t->tabBar()->geometry(); qDebug()<<"stackwidget geo"<<sw->geometry();*/

    Here's how it looks, I used a custom icon:

    Corner widget appeared

    If you need more space for the corner widget, you'll need to move the tab bar, because corner widget will cover it, you can do that using stylesheet. See this: Qt Style Sheets Examples: Customizing QTabWidget and QTabBar.

    Here's an example of stylesheet:

    t->setStyleSheet("QTabWidget::tab-bar " "{" "top: 50px;" /* push down by 50px */ "}");

    Here's how it looks with that being the only addition and change to my MRE:

    Extended tab widget corner widget

    Suggestion: QTabWidget::paintEvent might be a better solution.

  • 0 Votes
    2 Posts
    191 Views
    JonBJ

    @misscoffee
    So just set the size of the view and/or scene to the full size of the screen/desktop. You can also use void QWidget::showFullScreen() (see the warnings there).

    Be aware that widgets/windows have borders, and a title bar unless you specify otherwise, so the view/scene may not occupy every pixel of the screen, unless you take action, if that matters to you. IIRC, graphics scene/view places coordinate (0,0) in the center with x,y increasing right/up. You can use setSceneRect() to alter this.

  • 0 Votes
    1 Posts
    376 Views
    No one has replied