弹出窗口在从标题项的右上角开始的矩形中显示垂直标题文本

Posted

技术标签:

【中文标题】弹出窗口在从标题项的右上角开始的矩形中显示垂直标题文本【英文标题】:popup showing vertical header text in rectangle starting top right corner of header item 【发布时间】:2021-10-29 11:28:16 【问题描述】:

我尝试制作显示垂直标题项目名称的弹出标签,因为名称很大,我希望标题宽度正好是其数字的大小。 我制作了事件过滤器并制作了弹出对话框和 popuplabel qlabel。 但弹出窗口的大小大于标题项的大小。 如果我使大小等于矩形大小,则文本消失。 如果我调整弹出窗口的大小,它会产生更大的矩形显示文本,向下偏移对应于标题项的视觉索引。 这是代码:

#ifndef TABLEVIEW_H
#define TABLEVIEW_H

#include <QDialog>
#include <QEvent>
#include <QLabel>
#include <QMouseEvent>
#include <QTableView>
#include <QVBoxLayout>
#include <QHeaderView>
#include <QTimer>

class TableView : public QTableView 
    Q_OBJECT
        QDialog* popup;
    QLabel* popupLabel;
    int editor_index ;

public:

    TableView(QWidget* parent = Q_NULLPTR) :QTableView(parent) 
        viewport()->installEventFilter(this);
        horizontalHeader()->viewport()->installEventFilter(this);
        verticalHeader()->viewport()->installEventFilter(this);
        setMouseTracking(true);
        popup = new QDialog(this, Qt::Popup | Qt::ToolTip);
        //popup = new QDialog(viewport(), Qt::Popup | Qt::ToolTip);

        //QVBoxLayout* layout = new QVBoxLayout;
        popupLabel = new QLabel(popup);
        popupLabel->setWordWrap(false);
        //layout->addWidget(popupLabel);
        popupLabel->setTextFormat(Qt::RichText);        
        //popup->setLayout(layout);
        popup->installEventFilter(this);
        QTimer::singleShot(0, popup, &QWidget::hide);

    

    bool eventFilter(QObject* watched, QEvent* event) 
        //if (viewport() == watched) 
        if ((watched == horizontalHeader()->viewport() ||
            watched == verticalHeader()->viewport())) 
        
            if (event->type() == QEvent::MouseMove) 
            
                /*/
                if (popup)  //delete previous popup just in case
                    popup->contentsRect().setRect(0,0,0,0) ;
                
                if (popupLabel)  //delete previous popupLabel just in case
                    popupLabel->contentsRect().setRect(0,0,0,0);
                
                */
                /*
                ////////////////////////////////////////////////////////
                popup = new QDialog(this, Qt::Popup | Qt::ToolTip);
                //popup = new QDialog(viewport(), Qt::Popup | Qt::ToolTip);

                //QVBoxLayout* layout = new QVBoxLayout;
                popupLabel = new QLabel(popup);
                popupLabel->setWordWrap(false);
                //layout->addWidget(popupLabel);
                popupLabel->setTextFormat(Qt::RichText);
                //popup->setLayout(layout);
                popup->installEventFilter(this);
                QTimer::singleShot(0, popup, &QWidget::hide);
                ////////////////////////////////////////////////////////
                */

                QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);                
                QHeaderView* header = static_cast<QHeaderView*>(watched->parent());
                int mouse_pos = header->orientation() == Qt::Horizontal ? mouseEvent->x() : mouseEvent->y();
                int logical_index = header->logicalIndex(header->visualIndexAt(mouse_pos));
                                
                if (logical_index >= 0) 
                 // if mouse is over an item               
                    showPopup(logical_index, watched);                    
                                
                else 
                
                    popup->hide();
                
            
            else if (event->type() == QEvent::Leave) 
                popup->hide();
            
        
        else if (popup == watched) 
        
            if (event->type() == QEvent::Leave) 
            
                popup->hide();
            
        
        return QTableView::eventFilter(watched, event);
    

private:
    void showPopup(const int & logical_index, QObject* watched) const 
    
        if (logical_index >= 0)
        
        QHeaderView* header = static_cast<QHeaderView*>(watched->parent());

        QFont font("times", 12);
        QFontMetrics fm(font);
        int pixelsWide = fm.width("xxxxxx");
        int pixelsHigh = fm.height();

        QRect rect; // line edit rect in header's viewport's coordinates
        if (header->orientation() == Qt::Horizontal) 
            //rect.setLeft(header->sectionPosition(logical_index));
            rect.setLeft(header->sectionViewportPosition(logical_index));
            rect.setWidth(header->sectionSize(logical_index));
            rect.setTop(0);
            rect.setHeight(header->height());
        
        else 
            //rect.setTop((header->sectionPosition(logical_index)));
            rect.setTop((header->sectionViewportPosition(logical_index)));
            //QPoint point(0,header->sectionPosition(logical_index));
            //rect.setTop((mapToGlobal(point)).y() );

            //rect.topLeft())
            int cy = header->sectionSize(logical_index);
            rect.setHeight(header->sectionSize(logical_index));
            rect.setLeft(0);
            rect.setWidth(header->width());
            //rect.setCoords(rect.left(),rect.top(),rect.left()+rect.width(),rect.top()+rect.height());
        
        
        //rect.adjust(1, 1, 1, 1);        
        popupLabel->move(rect.bottomLeft());
        //popupLabel->move(rect.topLeft());
        //popupLabel->move(viewport()->mapToGlobal(rect.topLeft()));

        popupLabel->resize(rect.size());
        //popupLabel->setAlignment(Qt::AlignTop | Qt::AlignLeft);
        //popupLabel->show();

        //popupLabel->setFixedHeight(rect.height());
        //popupLabel->setFixedWidth(rect.width());
        //popupLabel->setFrame(false);
        //get current item text
        QString text = header->model()->
            headerData(logical_index, header->orientation()).toString();
        //int z=text.size();
        popupLabel->setText(text);
        //popupLabel->setFocus();
        ///////////////////////////////////////////////////////////////////////////
        //editor_index = logical_index; //save for future use
        popupLabel->installEventFilter(this->parent()); //catch focus out event
        //if user presses Enter it should close editor
        //connect(header_editor, SIGNAL(returnPressed()),
        //    ui->tableWidget, SLOT(setFocus()));
        //popupLabel->setGeometry(rect);
        //popupLabel->adjustSize();
        //popupLabel->setFixedSize(100, 100);
        popupLabel->show();
        ////////////////////////////////////////////////////////////////////////////
        //popup->move(viewport()->mapToGlobal(rect.bottomLeft()));
        popup->move(viewport()->mapToGlobal(rect.topLeft()));
        //popup->move(rect.topLeft());
        //popup->resize(rect.size());

        //popup->move(rect.bottomLeft());
        //popup->move(rect.topLeft());

        //popup->setFixedSize(100, popup->heightForWidth(100));
        //popup->setFixedSize(100, 100);

        //popupLabel->setText(text);
        //popupLabel->show();

        // popupLabel->setText(logical_index.data(Qt::DisplayRole).toString());
        //popup->adjustSize();
        //popup->setGeometry(rect);
        popup->show();
        //sleep 10 ms;
        return;// true; // filter out event
        
        else 
            popup->hide();
             //delete previous popup just in case
            popup->contentsRect().setRect(0, 0, 0, 0);
            //popup = nullptr;
            
             //delete previous popupLabel just in case
            popupLabel->contentsRect().setRect(0, 0, 0, 0);
            //popupLabel = nullptr;
            
            return; //false;
        
    
;

#endif // TABLEVIEW_H

【问题讨论】:

【参考方案1】:

我用超越比较来找出我改变了什么:

1.我将popupLabel移动到指向0,0

2.我将popup调整为rect.size()

如果没有足够的空间来显示文本,我会将popupLabelpopup调整为更大的尺寸。

代码:

#include <QApplication>
#include <QTableWidget>
#include <QStyledItemDelegate>
#include <QDialog>
#include <QEvent>
#include <QLabel>
#include <QMouseEvent>
#include <QTableView>
#include <QVBoxLayout>
#include <QHeaderView>
#include <QTimer>
#include <QDebug>

class TableModel :public QAbstractTableModel

    Q_OBJECT
public:
    int rowCount(const QModelIndex& parent = QModelIndex()) const
    
        return 4;
    
    int columnCount(const QModelIndex& parent = QModelIndex()) const
    
        return 2;
    
    QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const
    
        if (role == Qt::DisplayRole)
            return QString::number(index.row()) + QString::number(index.column());
        return QVariant();
    
;

class TableView : public QTableView 
    Q_OBJECT
        QDialog* popup;
    QLabel* popupLabel;
    int editor_index;

public:

    TableView(QWidget* parent = Q_NULLPTR) :QTableView(parent) 
        viewport()->installEventFilter(this);
        horizontalHeader()->viewport()->installEventFilter(this);
        verticalHeader()->viewport()->installEventFilter(this);
        setMouseTracking(true);
        popup = new QDialog(this, Qt::Popup | Qt::ToolTip);
        //popup = new QDialog(viewport(), Qt::Popup | Qt::ToolTip);

        //QVBoxLayout* layout = new QVBoxLayout;
        popupLabel = new QLabel(popup);
        popupLabel->setWordWrap(false);
        //layout->addWidget(popupLabel);
        popupLabel->setTextFormat(Qt::RichText);
        //popup->setLayout(layout);
        popup->installEventFilter(this);
        QTimer::singleShot(0, popup, &QWidget::hide);

    

    bool eventFilter(QObject* watched, QEvent* event) 
        //if (viewport() == watched) 
        if ((watched == horizontalHeader()->viewport() ||
            watched == verticalHeader()->viewport()))
        
            if (event->type() == QEvent::MouseMove)
            
                /*/
                if (popup)  //delete previous popup just in case
                    popup->contentsRect().setRect(0,0,0,0) ;
                
                if (popupLabel)  //delete previous popupLabel just in case
                    popupLabel->contentsRect().setRect(0,0,0,0);
                
                */
                /*
                ////////////////////////////////////////////////////////
                popup = new QDialog(this, Qt::Popup | Qt::ToolTip);
                //popup = new QDialog(viewport(), Qt::Popup | Qt::ToolTip);

                //QVBoxLayout* layout = new QVBoxLayout;
                popupLabel = new QLabel(popup);
                popupLabel->setWordWrap(false);
                //layout->addWidget(popupLabel);
                popupLabel->setTextFormat(Qt::RichText);
                //popup->setLayout(layout);
                popup->installEventFilter(this);
                QTimer::singleShot(0, popup, &QWidget::hide);
                ////////////////////////////////////////////////////////
                */

                QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);
                QHeaderView* header = static_cast<QHeaderView*>(watched->parent());
                int mouse_pos = header->orientation() == Qt::Horizontal ? mouseEvent->x() : mouseEvent->y();
                int logical_index = header->logicalIndex(header->visualIndexAt(mouse_pos));

                if (logical_index >= 0)
                 // if mouse is over an item               
                    showPopup(logical_index, watched);
                
                else
                
                    popup->hide();
                
            
            else if (event->type() == QEvent::Leave) 
                popup->hide();
            
        
        else if (popup == watched)
        
            if (event->type() == QEvent::Leave)
            
                popup->hide();
            
        
        return QTableView::eventFilter(watched, event);
    

private:
    void showPopup(const int& logical_index, QObject* watched) const
    
        if (logical_index >= 0)
        
            QHeaderView* header = static_cast<QHeaderView*>(watched->parent());

            QFont font("times", 12);
            QFontMetrics fm(font);
            int pixelsWide = fm.width("xxxxxx");
            int pixelsHigh = fm.height();

            QRect rect; // line edit rect in header's viewport's coordinates
            if (header->orientation() == Qt::Horizontal) 
                //rect.setLeft(header->sectionPosition(logical_index));
                rect.setLeft(header->sectionViewportPosition(logical_index));
                rect.setWidth(header->sectionSize(logical_index));
                rect.setTop(0);
                rect.setHeight(header->height());
            
            else 
                //rect.setTop((header->sectionPosition(logical_index)));
                rect.setTop((header->sectionViewportPosition(logical_index)));
                //QPoint point(0,header->sectionPosition(logical_index));
                //rect.setTop((mapToGlobal(point)).y() );

                //rect.topLeft())
                int cy = header->sectionSize(logical_index);
                rect.setHeight(header->sectionSize(logical_index));
                rect.setLeft(0);
                rect.setWidth(header->width());
                //rect.setCoords(rect.left(),rect.top(),rect.left()+rect.width(),rect.top()+rect.height());
            

            //rect.adjust(1, 1, 1, 1);        
            //popupLabel->move(rect.bottomLeft());
            //popupLabel->move(rect.topLeft());
            popupLabel->move(QPoint(0,0));
            popupLabel->resize(rect.size());
            //popupLabel->setAlignment(Qt::AlignTop | Qt::AlignLeft);
            //popupLabel->show();

            //popupLabel->setFixedHeight(rect.height());
            //popupLabel->setFixedWidth(rect.width());
            //popupLabel->setFrame(false);
            //get current item text
            QString text = header->model()->
                headerData(logical_index, header->orientation()).toString();
            //int z=text.size();
            popupLabel->setText(text);  
            qDebug() << rect << text;
            //popupLabel->setFocus();
            ///////////////////////////////////////////////////////////////////////////
            //editor_index = logical_index; //save for future use
            popupLabel->installEventFilter(this->parent()); //catch focus out event
            //if user presses Enter it should close editor
            //connect(header_editor, SIGNAL(returnPressed()),
            //    ui->tableWidget, SLOT(setFocus()));
            //popupLabel->setGeometry(rect);
            //popupLabel->adjustSize();
            //popupLabel->setFixedSize(100, 100);
            popupLabel->show();
            ////////////////////////////////////////////////////////////////////////////
            //popup->move(viewport()->mapToGlobal(rect.bottomLeft()));
            popup->move(viewport()->mapToGlobal(rect.topLeft()));
            //popup->move(rect.topLeft());
            popup->resize(rect.size());

            //popup->move(rect.bottomLeft());
            //popup->move(rect.topLeft());

            //popup->setFixedSize(100, popup->heightForWidth(100));
            //popup->setFixedSize(100, 100);

            //popupLabel->setText(text);
            //popupLabel->show();

            // popupLabel->setText(logical_index.data(Qt::DisplayRole).toString());
            //popup->adjustSize();
            //popup->setGeometry(rect);
            popup->show();
            //sleep 10 ms;
            return;// true; // filter out event
        
        else 
            popup->hide();
            //delete previous popup just in case
            popup->contentsRect().setRect(0, 0, 0, 0);
            //popup = nullptr;

             //delete previous popupLabel just in case
            popupLabel->contentsRect().setRect(0, 0, 0, 0);
            //popupLabel = nullptr;

            return; //false;
        
    
;
#include"main.moc"
int main(int argc, char* argv[])

    QApplication a(argc, argv);
    TableView view;
    view.setModel(new TableModel);
    view.show();
    return a.exec();

【讨论】:

以上是关于弹出窗口在从标题项的右上角开始的矩形中显示垂直标题文本的主要内容,如果未能解决你的问题,请参考以下文章

Angular:在关闭浏览器窗口之前显示材质弹出窗口

Internet Explorer 中的 Iframe 内不显示模态弹出窗口

如何使用显示多个对象项的视图并在从 Django 数据库中删除其中一项后显示 html?

如何在通过文本字段和圆形矩形按钮提供的表格视图单元格中显示数据

通达信drawrectrel是啥意思怎么用

CSS垂直和水平居中的Div [重复]