【问题标题】: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

【问题讨论】:

    标签: c++ qt


    【解决方案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();
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-06-13
      • 1970-01-01
      • 1970-01-01
      • 2012-12-10
      • 2011-07-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多