弹出窗口在从标题项的右上角开始的矩形中显示垂直标题文本
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()
如果没有足够的空间来显示文本,我会将popupLabel
和popup
调整为更大的尺寸。
代码:
#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();
【讨论】:
以上是关于弹出窗口在从标题项的右上角开始的矩形中显示垂直标题文本的主要内容,如果未能解决你的问题,请参考以下文章
Internet Explorer 中的 Iframe 内不显示模态弹出窗口
如何使用显示多个对象项的视图并在从 Django 数据库中删除其中一项后显示 html?