Qt:可调整大小且可移动的主窗口,没有标题栏

时间:2016-05-05 09:39:02

标签: qt titlebar qmainwindow

我需要绘制没有标题栏的Qt窗口。通常,只需设置CustomizeWindowHint窗口属性即可。但是窗口的大小和位置都是固定的。

我需要一个可移动可调整大小的窗口。 This帖子显示了如何手动移动窗口,所以我想知道是否有办法至少保持边框可调整大小。

当然我也可以手动调整窗口大小,但我希望跳窗和许多奇怪的行为,所以我希望有一种方法可以使用现有的功能

2 个答案:

答案 0 :(得分:2)

来自Qt::CustomizeWindowHint上的文档:

  

必须将此标志设置为允许更改WindowTitleHint,WindowSystemMenuHint,WindowMinimizeButtonHint,WindowMaximizeButtonHint和WindowCloseButtonHint标志。

基本上,如果没有其他标题栏提示,则不应使用Qt::CustomizeWindowHint

Qt::FramelessWindowHint与某些事件重新实现结合使用以进行拖动(请参阅solution to your other question)。您可以像这样显示尺寸:

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

可能需要使用大小的手柄和状态栏进行一些工作来处理无框窗口标志设置。

编辑,因为您没有使用状态栏,请在中央窗口小部件中添加“热点”以开始调整大小而不是移动,即检查鼠标是否位于右下角窗口并适当设置光标。如果他们点击,开始调整大小而不是移动。这可以通过重新实现鼠标事件来完成。

答案 1 :(得分:0)

编辑:我明白了

有一些跳跃行为,但这是一个工作手册调整大小/移动窗口而没有为我的个人项目实现的标题栏:

//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;