The function sizeincrement has no effect



  • I write a widget and set the sizeincrement with setsizeincrement(),want to the width to increase by the step of 145pixels. But I found no effect after set the sizeincrement. I use QT5 in windows 8.


  • Moderators

    Hi, welcome to devnet.

    As stated in the "documentation":http://qt-project.org/doc/qt-5/qwidget.html#sizeIncrement-prop the sizeIncrement property doesn't have effect on Windows platform.



  • Thanks.if I want to implementation this effect on windows platform,How can I?


  • Moderators

    There are no ready facilities in windows api to do it (that I know of), so you'd have to basically reimplement resizing. Detect mouse presses on window borders.When the mouse is pressed detect mouse moves and handle the stepping there. Might not be fun to implement.



  • is there no resize event or signal in QWindow or something?
    I mean there has to be, because Qt has to repaint the window when it is resized, somehow :D


  • Moderators

    There is a resizeEvent, but you get it after the window was resized. That's when OS sends it unfortunately.

    To resize in steps you would have to "block" resizing and manually resize to specific dimensions after detecting mouse move. Of course when you grow your window cursor is outside the window so you don't get mouseMove events either. You would have to track mouse movement in a timer or something.

    It's an ugly implementation. That's probably why Qt doesn't provide it if there is no direct OS support for it.



  • But can't you simply set the window size in the resize event? Even if that function is called after the window has been resized you can set the size programatically and that will trigger another resize so you need to be careful and check the values.
    But in theory that should be much simpler than your mouse move approach, even if that is a little dirty too because it may use an "unnecessary" resize..

    @
    void QWindow::resizeEvent(QResizeEvent * ev) {
    const int sizeIncrement = 16; // snap to 16 pixel size
    if (ev->size() != ev->oldSize())
    resize(sizeIncrement * qRound(ev->size().width() / sizeIncrement ), sizeIncrement * qRound(ev->size().height() / sizeIncrement)); // round to your "size increment" value
    }
    @


  • Moderators

    That's an option but i fear this will result in very jaggy motion.
    The purpose of this exercise is to resize in steps, eg.
    100, 110, 120, 130...
    The OP didn't say what's that for but if the layout of the window depends on these steps it might be important (or not).

    With suggested approach it would be something like:
    100, 103->100, 107->100, 111->110...
    It might jump around and not look good, especially with big steps, but I haven't checked of course.

    There's also question of mouse cursor position. Manually calling resize won't move the cursor, so I'm not exactly sure if the cursor will stay at the edge after few of these events.


  • Moderators

    I actually had some time before lunch so I decided to give both solutions a go.

    "Here's a little video":http://youtu.be/10vkSyHQF_I of the results. The video doesn't actually capture it well (framerate issue with my recorder), but the first method actually flickers far worse then I anticipated.



  • ok your first solution looks terrible, I didn't expect it to be that slow... :/
    maybe you can show the code for both option? the second looks fine I think.


  • Moderators

    It's not that it's slow, it's just very jumpy.

    Please remember this code is "demo quality" (very).
    For the first method I used basically your code(refactored a little):
    @
    QSize MainWindow::calcProperSize(QSize size) const
    {
    auto incw = sizeIncrement().width();
    auto inch = sizeIncrement().height();
    auto w = (int)floor((float)size.width() / incw) * incw;
    auto h = (int)floor((float)size.height() / inch) * inch;
    return QSize(w,h);
    }

    void MainWindow::resizeEvent(QResizeEvent *evt)
    {
    QMainWindow::resizeEvent(evt);

    if(ui->rbMethod1->isChecked())
    {
        if(evt->oldSize() != size())
            resize(calcProperSize(size()));
    }
    

    }
    @

    For the second one it's a little complicated. I "lock" resizing by using min/max size. I detect mouse press on the border using native event since window border is outside Qt jurisdiction. For the purpose of this demo I don't detect which border was pressed so it will only work for right and bottom. Mouse press activates timer. Timer event polls cursor position and does the resizing if needed.
    @
    bool MainWindow::nativeEvent(const QByteArray &eventType, void *message, long *result)
    {
    if(!ui->rbMethod2->isChecked())
    return false;

    MSG msg = *(MSG*)message;
    if(msg.message == WM_NCLBUTTONDOWN)
    {
        if(msg.wParam == HTBORDER)
          timerid = startTimer(16); //~60FPS
    }
    
    return false;
    

    }

    void MainWindow::timerEvent(QTimerEvent *evt)
    {
    if(!(QApplication::mouseButtons() & Qt::LeftButton))
    {
    killTimer(timerid);
    timerid = -1;
    }
    else
    {
    auto cp = mapFromGlobal(QCursor::pos());
    auto s = calcProperSize(QSize(cp.x(), cp.y()));

        if(s != size())
        {
            setMinimumSize(s);
            setMaximumSize(s);
        }
    }
    

    }
    @



  • Thanks very much.I test the 2rd one on QMainwindow and QWidget.The effect is satisfied.But there is some problem on the widget which I want to increase by step. Events are not delivered to the nativeEvent handler.Now I'm finding the reason of this problem.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.