Qt: изменяемое и подвижное главное окно без строки заголовка

Мне нужно нарисовать Qt-окно без строки заголовка. Как правило, это может быть легко, просто установив CustomizeWindowHint атрибут окна. Но тогда окно имеет фиксированный размер и положение.

Мне нужно подвижное окно с изменяемым размером. В этом посте показано, как перемещать окно вручную, поэтому мне интересно, есть ли способ, по крайней мере, сохранить размеры границ изменяемого размера.

Конечно, я также могу изменить размер окна вручную, но я ожидаю, что окна будут перепрыгивать и много странного поведения, поэтому я надеюсь, что есть способ использовать существующую функциональность

2 ответа

Из документов на Qt::CustomizeWindowHint:

Этот флаг должен быть установлен, чтобы разрешить изменение флагов WindowTitleHint, WindowSystemMenuHint, WindowMinimizeButtonHint, WindowMaximizeButtonHint и WindowCloseButtonHint.

В принципе, Qt::CustomizeWindowHint не предназначен для использования без других подсказок в строке заголовка.

использование Qt::FramelessWindowHint в сочетании с повторной реализацией какого-либо события для перетаскивания (см. решение вашего другого вопроса). Вы можете получить контроль размера, чтобы показать примерно так:

auto statusBarWidget = statusBar();
statusBarWidget->setSizeGripEnabled(true);

Возможно, вам придется поработать с ручкой размера и строкой состояния, чтобы работать с установленным флагом безрамного окна.

Редактировать: поскольку вы не используете строку состояния, добавьте "горячую точку" в ваш центральный виджет, чтобы начать изменение размера вместо перемещения, т.е. проверьте, находится ли мышь в правом нижнем углу окна, и установите курсор соответствующим образом. Если они нажмут, начните изменять размер, а не двигать Все это может быть сделано путем переопределения событий мыши.

Редактировать: я понял


Есть некоторые прыжки, но это рабочее руководство по изменению размера / перемещению окна без строки заголовка, которое я реализовал для своего личного проекта:

//Below two methods partially from Qt Shaped Clock example
void MainWindow::mousePressEvent(QMouseEvent *event){
//From Qt Documentation:
//Reason why pos() wasn't working is because the global
//position at time of event may be very different
//This is why the mpos = event->pos(); line before was
//possibly causing jumping behavior

     if (event->button() == Qt::LeftButton){
         //Coordinates have been mapped such that the mouse position is relative to the
         //upper left of the main window
         mpos = event->globalPos() - frameGeometry().topLeft();

         //At the moment of mouse click, capture global position and
         //lock the size of window for resizing
         global_mpos = event->globalPos();
         storeWidth = this->width();
         storeHeight= this->height();

         event->accept();

     }   

}

void MainWindow::mouseMoveEvent(QMouseEvent *event){

    //mapped mouse relative to upper left of window
    rs_mpos=event->globalPos()-frameGeometry().topLeft();//general position tracker for resizing
    QTextStream out(stdout);

    //How much of the corner is considered a "resizing zone"
    //I was experiencing jumping behavior with rs_size is 10 so
    //I recommend rs_size=50
    int rs_size=50;

    //Big if statement checks if your mouse is in the upper left,
    //upper right, lower left, and lower right 
    if ( (abs(rs_mpos.x()) < rs_size && abs(rs_mpos.y()) < rs_size) ||
     (abs(rs_mpos.x()) > this->width()-rs_size && abs(rs_mpos.y()) <rs_size) ||
     (abs(rs_mpos.x()) < rs_size && abs(rs_mpos.y())> this->height()-rs_size) ||
     (abs(rs_mpos.x()) > this->width()-rs_size && abs(rs_mpos.y())> this->height()-rs_size)

     ){



         //Below for debugging
         /*
         out << rs_mpos.x() << " , " << rs_mpos.y() << "\n";
         out << "window: " << this->width() << " , " << this->height() << "\n";
         out << "globalpos: " << event->globalPos().x() << " , " 
             << event->globalPos().y() << "\n";
         */

        //Use 2x2 matrix to adjust how much you are resizing and how much you
        //are moving. Since the default coordinates are relative to upper left
        //You cannot just have one way of resizing and moving the window.
        //It will depend on which corner you are referring to

        //adjXfac and adjYfac are for calculating the difference between your
        //current mouse position and where your mouse was when you clicked.
        //With respect to the upper left corner, moving your mouse to the right
        //is an increase in coordinates, moving mouse to the bottom is increase
        //etc.
        //However, with other corners this is not so and since I chose to subtract
        //This difference at the end for resizing, adjXfac and adjYfac should be
        //1 or -1 depending on whether moving the mouse in the x or y directions
        //increases or decreases the coordinates respectively. 

        //transXfac transYfac is to move the window over. Resizing the window does not
        //automatically pull the window back toward your mouse. This is what
        //transfac is for (translate window in some direction). It will be either
        //0 or 1 depending on whether you need to translate in that direction.

        //Initiate matrix
        int adjXfac=0;
        int adjYfac=0;
        int transXfac=0;
        int transYfac=0;

        //Upper left corner section
        if ( (abs(rs_mpos.x()) < rs_size && abs(rs_mpos.y()) < rs_size)){
        this->setCursor(Qt::SizeFDiagCursor);



             //Upper left. No flipping of axis, no translating window
             adjXfac=1;
             adjYfac=1;

             transXfac=0;
             transYfac=0;



        }
        //Upper right corner section
        else if(abs(rs_mpos.x()) > this->width()-rs_size &&
                abs(rs_mpos.y()) <rs_size){
            this->setCursor(Qt::SizeBDiagCursor);


            //upper right. Flip displacements in mouse movement across x axis
            //and translate window left toward the mouse
            adjXfac=-1;
            adjYfac=1;

            transXfac = 1;
            transYfac =0;

         }

         //Lower left corner section
         else if(abs(rs_mpos.x()) < rs_size &&
                 abs(rs_mpos.y())> this->height()-rs_size){
            this->setCursor(Qt::SizeBDiagCursor);

            //lower left. Flip displacements in mouse movement across y axis
            //and translate window up toward mouse
            adjXfac=1;
            adjYfac=-1;

            transXfac=0;
            transYfac=1;


          }
          //Lower right corner section
          else if(abs(rs_mpos.x()) > this->width()-rs_size &&
                  abs(rs_mpos.y())> this->height()-rs_size){
              this->setCursor(Qt::SizeFDiagCursor);

             //lower right. Flip mouse displacements on both axis and
             //translate in both x and y direction left and up toward mouse.
             adjXfac=-1;
             adjYfac=-1;

             transXfac=1;
             transYfac=1;
            }

       if (event->buttons()==Qt::LeftButton ){

           //Calculation of displacement. adjXfac=1 means normal displacement
           //adjXfac=-1 means flip over axis     
           int adjXdiff = adjXfac*(event->globalPos().x() - global_mpos.x());

           int adjYdiff = adjYfac*(event->globalPos().y() - global_mpos.y());

           //if transfac is 1 then movepoint of mouse is translated     
           QPoint movePoint(mpos.x() - transXfac*adjXdiff, mpos.y()-transYfac*adjYdiff);
           move(event->globalPos()-movePoint);
           resize(storeWidth-adjXdiff, storeHeight-adjYdiff);

           event->accept();


         }

    }

     //in any move event if it is not in a resize region use the default cursor
     else{

         this->setCursor(Qt::ArrowCursor);


          //simple move section
          if (event->buttons()==Qt::LeftButton &&
              resizeZone==false){
              move(event->globalPos() - mpos);
              event->accept();
          }


     }

}

Установите это в своем заголовочном файле

private:
    QPoint mpos; //For dragging, relative mouse position to upper left
    QPoint global_mpos; //For resizing, global mouse position at mouse click
    QPoint rs_mpos; //for resizing
    int storeWidth; //fix window size at mouseclick for resizing
    int storeHeight;
Другие вопросы по тегам