- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我创建了一个小部件类(C++
)ToolTray
,它基本上是在QHboxLayout
中添加的几个QToolButton
>。用户使用这些按钮进行 Save
、Open
等操作。最初,添加按钮时将 toolButtonStyle
设置为 Qt::ToolButtonTextBesideIcon
。
如果新尺寸不足以显示文本和图标,我想在 resizeEvent
中将 toolButtonStyle
更改为 Qt::ToolButtonIconOnly
QToolButton
。见下图:
如果调整了窗口大小并且新的大小足以显示所有 QToolButton 的文本和图标,则 toolButtonStyle
应该改回 Qt::ToolButtonTextBesideIcon
.
我尝试用下面的代码实现这个:
void ToolTray::resizeEvent(QResizeEvent *event)
{
int totalWidth = 0;
bool mode = runBtn_->toolButtonStyle() == Qt::ToolButtonStyle::ToolButtonIconOnly;
// Mode => True => For ICON Only
// Mode => False => For ICON + Text
for (auto btn: toolBtns_) {
if (btn->isVisible())
totalWidth += btn->size().width();
}
qDebug() << "Total Width: " << totalWidth ;
qDebug() << "Event Size: " << event->size() << " Old size " << event->oldSize();
if (event->oldSize().isEmpty()) // Ignore ResizeEvent for QSize(-1,-1)
return;
if (mode) { // Already Small
if (event->size().width() < preferedFullWidth_)
return;
for (auto btn: toolBtns_) {
if (btn == moreBtn_)
continue;
btn->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
}
return;
}
// The QToolButtons are Text Beside Icon
if (event->size().width() >= totalWidth)
return;
qDebug() << "Here";
for (auto btn: toolBtns_)
btn->setToolButtonStyle(Qt::ToolButtonIconOnly);
preferedFullWidth_ = totalWidth;
}
但是,我无法实现我想要的:
每当我尝试缩小窗口的大小时,QToolButton 的文本首先开始裁剪,在进一步缩小尺寸后,ToolButtonStyle
更改为 Qt::ToolButtonIconOnly
。我不想剪裁发生。
我还想在我的实现中添加一些余量(或滞后)。就像一旦 QToolButton 在特定宽度更改为 Qt::ToolButtonIconOnly
,那么宽度应该大于 preferedFullWidth_ + 一定的边距以切换回 Qt::ToolButtonTextBesideIcon
。
最佳答案
工具栏似乎是a theme这周……:)
所以您的想法基本上是正确的,但棘手的部分是计算出所需的大小。不幸的是 QToolBar
layout是完全私有(private)的,因此我们必须自己解决问题(即使它继承自 QLayout
,您无法通过 QToolBar::layout()
获取它的实例)。
此实现相当基础,可能无法处理所有情况(我只测试了基本操作,没有自定义小部件等),但它确实适用于此(在 Windows 和 Linux 上以各种样式测试)。
已添加:我知道您没有要求 QToolBar
具体来说,但这就是你基本上描述的......我不确定为什么要重新发明那个轮子(QToolBar
可以放置在任何布局中,不必在主窗口中),但如果你是实现你自己的版本我认为这个例子中的很多内容仍然适用。我个人也几乎总是使用 QAction
s 用于触发 UI 事件(相对于按钮),因为它们可以分配给任意数量的 UI 元素(工具栏、菜单栏、上下文菜单、窗口快捷方式等)。
添加边距/滞后留给读者作为练习... :) 我不认为它需要一个,但你可以填充 m_expandedSize
在 initSizes()
有一些任意余量。
折叠工具栏
#include <QtWidgets>
class CollapsingToolBar : public QToolBar
{
Q_OBJECT
public:
explicit CollapsingToolBar(QWidget *parent = nullptr) : CollapsingToolBar(QString(), parent) {}
explicit CollapsingToolBar(const QString &title, QWidget *parent = nullptr) :
QToolBar(title, parent)
{
initSizes();
// If icon sizes change we need to recalculate all the size hints, but we need to wait until the buttons have adjusted themselves, so we queue the update.
connect(this, &QToolBar::iconSizeChanged, [this](const QSize &) {
QMetaObject::invokeMethod(this, "recalcExpandedSize", Qt::QueuedConnection);
});
// The drag handle can mess up our sizing, update preferred size if it changes.
connect(this, &QToolBar::movableChanged, [this](bool movable) {
const int handleSz = style()->pixelMetric(QStyle::PM_ToolBarHandleExtent, nullptr, this);;
m_expandedSize = (movable ? m_expandedSize + handleSz : m_expandedSize - handleSz);
adjustForSize();
});
}
protected:
// Monitor action events to keep track of required size.
void actionEvent(QActionEvent *e) override
{
QToolBar::actionEvent(e);
int width = 0;
switch (e->type())
{
case QEvent::ActionAdded:
// Personal pet-peeve... optionally set buttons with menus to have instant popups instead of splits with the main button doing nothing.
//if (QToolButton *tb = qobject_cast<QToolButton *>(widgetForAction(e->action())))
// tb->setPopupMode(QToolButton::InstantPopup);
//Q_FALLTHROUGH;
case QEvent::ActionChanged:
width = widthForAction(e->action());
if (width <= 0)
return;
if (e->type() == QEvent::ActionAdded || !m_actionWidths.contains(e->action()))
m_expandedSize += width + m_spacing;
else
m_expandedSize = m_expandedSize - m_actionWidths.value(e->action()) + width;
m_actionWidths.insert(e->action(), width);
break;
case QEvent::ActionRemoved:
if (!m_actionWidths.contains(e->action()))
break;
width = m_actionWidths.value(e->action());
m_expandedSize -= width + m_spacing;
m_actionWidths.remove(e->action());
break;
default:
return;
}
adjustForSize();
}
bool event(QEvent *e) override
{
// Watch for style change
if (e->type() == QEvent::StyleChange)
recalcExpandedSize();
return QToolBar::event(e);
}
void resizeEvent(QResizeEvent *e) override
{
adjustForSize();
QToolBar::resizeEvent(e);
}
private slots:
// Here we do the actual switching of tool button style based on available width.
void adjustForSize()
{
int availableWidth = contentsRect().width();
if (!isVisible() || m_expandedSize <= 0 || availableWidth <= 0)
return;
switch (toolButtonStyle()) {
case Qt::ToolButtonIconOnly:
if (availableWidth > m_expandedSize)
setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
break;
case Qt::ToolButtonTextBesideIcon:
if (availableWidth <= m_expandedSize)
setToolButtonStyle(Qt::ToolButtonIconOnly);
break;
default:
break;
}
}
// Loops over all previously-added actions and re-calculates new size (eg. after icon size change)
void recalcExpandedSize()
{
if (m_actionWidths.isEmpty())
return;
initSizes();
int width = 0;
QHash<QAction *, int>::iterator it = m_actionWidths.begin();
for ( ; it != m_actionWidths.end(); ++it) {
width = widthForAction(it.key());
if (width <= 0)
continue;
m_expandedSize += width + m_spacing;
it.value() = width;
}
adjustForSize();
}
private:
void initSizes()
{
// Preload some sizes based on style settings.
// This is the spacing between items
m_spacing = style()->pixelMetric(QStyle::PM_ToolBarItemSpacing, nullptr, this);
// Size of a separator
m_separatorWidth = style()->pixelMetric(QStyle::PM_ToolBarSeparatorExtent, nullptr, this);
// The layout margins (we can't even get the private QToolBarLayout via layout() so we figure it out like it does)
m_expandedSize = (style()->pixelMetric(QStyle::PM_ToolBarItemMargin, nullptr, this) + style()->pixelMetric(QStyle::PM_ToolBarFrameWidth, nullptr, this)) * 2;
// And the size of the drag handle if we have one
if (isMovable())
m_expandedSize += style()->pixelMetric(QStyle::PM_ToolBarHandleExtent, nullptr, this);
}
int widthForAction(QAction *action) const
{
// Try to find how wide the action representation (widget/separator) is.
if (action->isSeparator())
return m_separatorWidth;
if (QToolButton *tb = qobject_cast<QToolButton *>(widgetForAction(action))) {
const Qt::ToolButtonStyle oldStyle = tb->toolButtonStyle();
// force the widest size
tb->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
const int width = tb->sizeHint().width();
tb->setToolButtonStyle(oldStyle);
return width;
}
if (const QWidget *w = widgetForAction(action))
return w->sizeHint().width();
return 0;
}
int m_expandedSize = -1; // The maximum size we need with all buttons expanded and allowing for margins/etc
int m_spacing = 0; // Layout spacing between items
int m_separatorWidth = 0; // Width of separators
QHash<QAction *, int> m_actionWidths; // Use this to track action additions/removals/changes
};
测试/演示
// An XPM icon ripped from QCommonStyle
static const char * const info_xpm[]={
"32 32 5 1",
". c None",
"c c #000000",
"* c #999999",
"a c #ffffff",
"b c #0000ff",
"...........********.............",
"........***aaaaaaaa***..........",
"......**aaaaaaaaaaaaaa**........",
".....*aaaaaaaaaaaaaaaaaa*.......",
"....*aaaaaaaabbbbaaaaaaaac......",
"...*aaaaaaaabbbbbbaaaaaaaac.....",
"..*aaaaaaaaabbbbbbaaaaaaaaac....",
".*aaaaaaaaaaabbbbaaaaaaaaaaac...",
".*aaaaaaaaaaaaaaaaaaaaaaaaaac*..",
"*aaaaaaaaaaaaaaaaaaaaaaaaaaaac*.",
"*aaaaaaaaaabbbbbbbaaaaaaaaaaac*.",
"*aaaaaaaaaaaabbbbbaaaaaaaaaaac**",
"*aaaaaaaaaaaabbbbbaaaaaaaaaaac**",
"*aaaaaaaaaaaabbbbbaaaaaaaaaaac**",
"*aaaaaaaaaaaabbbbbaaaaaaaaaaac**",
"*aaaaaaaaaaaabbbbbaaaaaaaaaaac**",
".*aaaaaaaaaaabbbbbaaaaaaaaaac***",
".*aaaaaaaaaaabbbbbaaaaaaaaaac***",
"..*aaaaaaaaaabbbbbaaaaaaaaac***.",
"...caaaaaaabbbbbbbbbaaaaaac****.",
"....caaaaaaaaaaaaaaaaaaaac****..",
".....caaaaaaaaaaaaaaaaaac****...",
"......ccaaaaaaaaaaaaaacc****....",
".......*cccaaaaaaaaccc*****.....",
"........***cccaaaac*******......",
"..........****caaac*****........",
".............*caaac**...........",
"...............caac**...........",
"................cac**...........",
".................cc**...........",
"..................***...........",
"...................**..........."};
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr)
: QMainWindow(parent)
{
QToolBar* tb = new CollapsingToolBar(this);
tb->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
tb->setAllowedAreas(Qt::TopToolBarArea | Qt::BottomToolBarArea);
QIcon icon = QIcon(QPixmap(info_xpm));
for (int i=0; i < 6; ++i)
tb->addAction(icon, QStringLiteral("Action %1").arg(i));
addToolBar(tb);
show();
// Adding another action after show() may collapse all the actions if the new toolbar preferred width doesn't fit the window.
// Only an issue if the toolbar size hint was what determined the window width to begin with.
//tb->addAction(icon, QStringLiteral("Action After"));
// Test setting button style after showing (comment out the one above)
//tb->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
// Test changing icon size after showing.
//tb->setIconSize(QSize(48, 48));
// Try this too...
//tb->setMovable(false);
}
};
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
//QApplication::setStyle("Fusion");
//QApplication::setStyle("windows");
MainWindow w;
return app.exec();
}
关于c++ - 根据窗口大小动态更改 QToolButtons 的 ToolButtonStyle,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57913277/
这个问题在这里已经有了答案: C sizeof a passed array [duplicate] (7 个回答) 8年前关闭。 在一个函数中,我声明了一个数组: int char_count_ar
简而言之,文件系统如何与 block 设备通信? 最佳答案 我对 block 大小不太了解。我认为 ext4(Linux)的文件系统的 block 大小是 4KB,考虑到现代处理器的页面大小(4KB)
我知道 tinyint(1) 和 tinyint(2) 具有相同的存储空间范围。 唯一的区别是显示宽度不同。这是否意味着 tinyint(1) 将存储所有类型的整数但只正确显示 0 到 9 的范围?而
今晚我已经研究了以下代码几个小时,但我只是摸不着头脑。 当使用函数从标准输入填充数组时,我不断收到“大小 8 的无效写入”和“大小 8 的无效读取”。 如有任何帮助,我们将不胜感激...我知道 Sta
我有一个 valgrind 错误,我不知道如何摆脱它们: ==5685== Invalid read of size 8 ==5685== at 0x4008A1: main (in /home
我对 Hadoop 的概念有点困惑。 Hadoop block 大小、拆分大小和 block 大小 之间有什么区别? 提前致谢。 最佳答案 block 大小和 block 大小相同。 拆分大小 可能与
我想不出一个好的标题,所以希望可以。 我正在做的是创建一个离线 HTML5 webapp。 “出于某些原因”我不希望将某些文件放在缓存 list 中,而是希望将内容放在 localStorage 中。
无法将 xamarin apk 大小减少到 80 MB 以下,已执行以下操作: 启用混淆器 配置:发布 平台:事件(任何 CPU)。 启用 Multi-Dex:true 启用开发人员检测(调试和分析)
我正在开发一个程序,需要将大量 csv 文件(数千个)加载到数组中。 csv 文件的尺寸为 45x100,我想创建一个尺寸为 nx45x100 的 3-d 数组。目前,我使用 pd.read_csv(
Hello World 示例的 React Native APK 大小约为 20M (in recent versions),因为支持不同的硬件架构(ARMv7、ARMv8、X86 等),而同一应用程
我有一个包含 n 个十进制元素的列表,其中每个元素都是两个字节长。 可以说: x = [9000 , 5000 , 2000 , 400] 这个想法是将每个元素拆分为 MSB 和 LSB 并将其存储在
如何设置 GtKTextView 的大小?我想我不能使用 gtk_widget_set_usize。 最佳答案 您不能直接控制小部件的大小,而是由其容器完成。您可以使用 gtk_widget_set_
这个问题在这里已经有了答案: c++ sizeof() of a class with functions (7 个答案) 关闭 5 年前。 结果是 12。 foobar 函数存储在内存中的什么位置
当我在 ffmpeg(或任何其他程序)中使用这样的命令时: ffmpeg -i input.mp4 image%d.jpg 所有图像的组合文件大小总是比视频本身大。我尝试减少每秒帧数、降低压缩设置、模
我是 clojurescript 的新手。 高级编译后出现“77 KB”的javascript文件是否正常? 我有一个 clojurescript 文件: 我正在使用 leinigen: lein c
我想要一个 QPixmap尺寸为 50 x 50。 我试过 : QPixmap watermark(QSize(50,50)); watermark.load(":/icoMenu/preparati
我正在尝试从一篇研究论文中重新创建一个 cnn,但我对深度学习还是个新手。 我得到了一个大小为 32x32x7 的 3d 补丁。我首先想执行一个大小为 3x3 的卷积,具有 32 个特征和步幅为 2。
我一直在尝试调整 View Controller 内的 View 大小,但到目前为止没有运气。基本上,我的 View 最底部有一个按钮,当方向从纵向更改为横向时,该按钮不再可见,因为它现在太靠下了。
如何使用此功能检查图像的尺寸?我只是想在上传之前检查一下... $("#LINK_UPLOAD_PHOTO").submit(function () { var form = $(this);
我用 C++ 完成了这个,因为你可以通过引用传递参数。我无法弄清楚如何在 JavaScript 中执行此操作。我的代码需要更改什么?我的输出是1 this.sizeOfBst = function()
我是一名优秀的程序员,十分优秀!