Qt:不带标题栏的可调整大小和可移动的主窗口



我需要绘制一个没有标题栏的Qt窗口。一般来说,只需设置CustomizeWindowHint窗口属性就可以轻松实现。但那个么窗户就有固定的大小和位置。

我需要一个可移动大小可调整的窗口。这篇文章展示了如何手动移动窗口,所以我想知道是否有一种方法至少可以调整边框的大小。

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

来自Qt::CustomizeWindowHint:上的文档

此标志必须设置为允许更改WindowTitleHint、WindowSystemMenuHint、Window MinimizeButtonHint、windowMaximizeButtonHind和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;

最新更新