2.3Qtabwidget和Qlistwidget和Qscrollarea

Qtabwidget和Qlistwidget

Qtabwidget

img

#include "widget.h"
#include "ui_widget.h"
#include <QHBoxLayout>
#include <QTabWidget>
#include "form.h"
#include <QDebug>
#include <QTabBar>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    QHBoxLayout* lay = new QHBoxLayout(this);

    QTabWidget *pTabWidget = new QTabWidget(this);
    pTabWidget->setTabsClosable(true);//显示关闭按钮,配合这个void tabCloseRequested(int index)使用
    pTabWidget->setMovable(true);//是tab可以移动
    pTabWidget->setTabPosition(QTabWidget::North);//设置tab在上下左右哪几个方位
    pTabWidget->setTabShape(QTabWidget::Rounded);  //梯形tab

    QWidget *w1 = new QWidget;
    w1->setStyleSheet("background-color:rgb(54,54,54)");

    QWidget *w2 = new QWidget;
    w2->setStyleSheet("background-color:rgb(54,154,54)");

    QWidget *w3 = new QWidget;
    w3->setStyleSheet("background-color:rgb(54,54,154)");

    pTabWidget->insertTab(0, w1, "tab1");
    pTabWidget->insertTab(1, w2, "tab2");
    pTabWidget->insertTab(2, w3, "tab3");
    //pTabWidget->addTab(new QTabBar, "");

    Form* f = new Form;//自定义的一个文件,主要写的是一个wiget加几个按钮
    pTabWidget->insertTab(3, f, "tab4");

    //pTabWidget->setTabVisible(2, false);
    pTabWidget->setTabToolTip(2, "this is tab2");

    lay->addWidget(pTabWidget);

    /*
Q_SIGNALS:这是tabwiget的信号
    void currentChanged(int index);当当前选择的标签页发生变化时,就会发出这个信号
    void tabCloseRequested(int index);当用户请求关闭某个标签页时,就会发出这个信号
    void tabBarClicked(int index);当用户单击某个标签页时,就会发出这个信号
    void tabBarDoubleClicked(int index);当用户双击某个标签页时,就会发出这个信号
    */

    connect(pTabWidget, &QTabWidget::currentChanged, [=](int index){
        qDebug() << "index = " << index;
    });

    connect(pTabWidget, &QTabWidget::tabBarDoubleClicked, [=](int index){
        qDebug() << "tabBarDoubleClicked index = " << index;
    });

    connect(pTabWidget, &QTabWidget::tabBarClicked, [=](int index){
        qDebug() << "tabBarClicked index = " << index;
    });

    connect(pTabWidget, &QTabWidget::tabCloseRequested, [=](int index){
        qDebug() << "tabCloseRequested index = " << index;
        pTabWidget->removeTab(index);  // 关闭tab
    });
}

Widget::~Widget()
{
    delete ui;
}


QListwidget

img

添加qrc文件

img

添加列表项(还有自定义列表项)

img

QListWidgetItem* pItem1 = new QListWidgetItem(QIcon(":/resources/kits.png"), "Kits");
ui->listWidget->addItem(pItem1);
//添加自己写的item
QListWidgetItem * pItem6 = new QListWidgetItem;
cuseritem * f =new cuseritem(this);
ui->listWidget->setItemWidget(pItem6,f);    

img

添加右键菜单

img

#include "_11_ListWidget02.h"
_11_ListWidget02::_11_ListWidget02(QWidget *parent)
    : QWidget(parent)
{
    ui.setupUi(this);
    QListWidgetItem* pItem1 = new QListWidgetItem(QIcon(":/_11_ListWidget02/resources/kits.png"), "Kits");
    QListWidgetItem* pItem2 = new QListWidgetItem(QIcon(":/_11_ListWidget02/resources/env.png"), u8"环境");
    QListWidgetItem* pItem3 = new QListWidgetItem(QIcon(":/_11_ListWidget02/resources/editor.png"), u8"编辑器");
    QListWidgetItem* pItem4 = new QListWidgetItem(QIcon(":/_11_ListWidget02/resources/vim.png"), "FakeVim");
    QListWidgetItem* pItem5 = new QListWidgetItem(QIcon(":/_11_ListWidget02/resources/help.png"), u8"帮助");
   
    ui.listWidget->addItem(pItem1);
    ui.listWidget->addItem(pItem2);
    ui.listWidget->addItem(pItem3);
    ui.listWidget->addItem(pItem4);
    ui.listWidget->addItem(pItem5);
    initRightMenu();
    //设置菜单策略,必须设置,不然无法显示菜单
    ui.listWidget->setContextMenuPolicy(Qt::CustomContextMenu);
    //连接信号槽
    connect(ui.listWidget, &QListWidget::customContextMenuRequested,
        this, &_11_ListWidget02::on_PopupRightMenu);

}

_11_ListWidget02::~_11_ListWidget02()
{}

void _11_ListWidget02::initRightMenu()
{
    m_pRightMenu = new QMenu(this);

    QAction* pAc1 = new QAction(u8"动作1", this);
    QAction* pAc2 = new QAction(u8"动作2", this);
    QAction* pAc3 = new QAction(u8"动作3", this);
    QAction* pAc4 = new QAction(u8"删除", this);

    m_pRightMenu->addAction(pAc1);
    m_pRightMenu->addAction(pAc2);
    m_pRightMenu->addAction(pAc3);
    m_pRightMenu->addAction(pAc4);
    connect(pAc4, &QAction::triggered, [=] {

        // 动态删除 就是你必须首先知道你要删的东西的名字,才能删除
        /*QList<QListWidgetItem*> list;
        list = ui.listWidget->findItems("Kits", Qt::MatchCaseSensitive);

        QListWidgetItem* sel = list[0];
        int r = ui.listWidget->row(sel);

        QListWidgetItem* item = ui.listWidget->takeItem(r);
        ui.listWidget->removeItemWidget(item);

        delete item;*/

        QListWidgetItem* item = ui.listWidget->currentItem();//返回当前被选中的 QListWidgetItem
        // ui.listWidget 中获取当前选中的 QListWidgetItem 的指针,并将其赋值给 item 变量。
        ui.listWidget->removeItemWidget(item);
        delete item;
        });

}

void _11_ListWidget02::on_PopupRightMenu(const QPoint & pos)
{
    QListWidgetItem*pTem=ui.listWidget->itemAt(pos);//可以获取鼠标移动到的那个QListWidgetItem的指针
    if (!pTem) {
        return;
    }
    m_pRightMenu->exec(QCursor::pos());//根据你鼠标位置显示菜单
}

一些使用vs的小细节

  • 使用vs写槽函数的时候,不能直接加上slots
    img
  • 要先删除slots,然后鼠标点击函数名称,按住alt+enter选中创建函数定义
    img
  • 在下面那个框中按住ctrl+s,然后再加slots:
    img

图标模式及

img
默认是列表模式,所以需要手动用代码更改为图标模式
img
img

#include "ch212_listwidget_03.h"
#include <QVBoxLayout>
#include <QListWidget>

ch212_listwidget_03::ch212_listwidget_03(QWidget *parent)
    : QWidget(parent)
{
    resize(600 + 60 + 25, 500);

    QVBoxLayout* pMainVLayout = new QVBoxLayout(this);

    QListWidget* pListWidget = new QListWidget(this);
    pListWidget->setViewMode(QListView::IconMode);
    pListWidget->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);//将水平滚动条的策略设置为“始终关闭”
    pListWidget->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);//垂直滚动条的策略设置为“根据需要显示”

    int vScrollBarWidth = 30;

    /*
    //给item添加背景色是为了更好的识别每个item
    QString qss = "QListWidget{border:none; background:rgb(251,251,251);} \
        QListWidget::item{background:blue;  \
        margin-left:20px;  \
        margin-top:10px; \
    }";

    */

    QString qssLW = QString("QScrollBar{width:%1px;background:rgba(255, 255, 255,100%);margin:0px, 0px, 0px, 0px;}\
              QScrollBar::handle:vertical{width:8px;background:rgba(162, 163, 165, 100%);border-radius:4px;min-height:60;}\
              QScrollBar::handle:vertical:hover{width:8px;background:rgba(115,118,118, 100%);border-radius:4px;min-height:60;}\
              QScrollBar::add-page:vertical,QScrollBar::sub-page:vertical{background:rgba(255, 255, 255, 100%);border-radius:4px;}\
              QScrollBar::top-arrow:vertical,QScrollBar::bottom-arrow:vertical{border: none;background: none;color: none;}\
              QScrollBar::add-line:vertical{border:none;background:none;}\
              QScrollBar::sub-line:vertical{border:none;background:none;}\
              QListWidget{background-color:rgb(255,255,255);border:none;} \
              QListWidget::item{  \
              /*background:blue;*/  \
              margin-left:20px;  \
              margin-right:20px; \
              margin-top:10px; \
              } \
    ").arg(QString::number(vScrollBarWidth));//1%被vScrollBarWidth替代

    pListWidget->setStyleSheet(qssLW);//setStyleSheet()函数接受一个QString类型的参数作为样式表

    //180包括margin-left的值
    //如果QListWidget::item没有写margin-right:20px,增加竖直滑动条和最后一列的间隙为margin-left的一半即可,这样看着美观
    //如果QListWidget::item写了margin-right:20px, vScrollBarWidth + 1即可
    pListWidget->setFixedWidth(180 * 3 +  vScrollBarWidth + 1);

    for (int i = 0; i < 15; i++)
    {
        //:/ch212_listwidget_03/resources/env.png
        QIcon icon(":/ch212_listwidget_03/resources/env.png");

        QString name = QString(u8"用户%1").arg(QString::number(i));
    
        QListWidgetItem* pItem = new QListWidgetItem(icon, name);
        pItem->setSizeHint(QSize(180, 180));
        pListWidget->addItem(pItem);
    }

    pMainVLayout->addWidget(pListWidget);
}

QListwidget

img
如果像这里添加的string标签,就可以直接代替上一节的好多item

    m_pListWidget = new QListWidget(this);
    m_pListWidget->setFixedWidth(150);
 /*   m_pListWidget->setFrameShape(QFrame::NoFrame);
    m_pListWidget->setFocusPolicy(Qt::NoFocus);*/

    m_textList << u8"基本设置" << u8"云盘设置" << u8"下载设置" << u8"接管设置" << u8"任务管理" << u8"����"
        << u8"悬浮窗" << u8"高级设置";

    m_pListWidget->addItems(m_textList);

img

R"()" 中的括号内可以是任何字符序列,除了右括号本身。原始字符串字面值会将括号内的字符序列视为普通字符,不进行转义和解释。这意味着你可以在原始字符串字面值中直接包含特殊字符、转义序列和换行符,而无需手动转义。

这里主要是qss的R,主要说明好像是可以省去之前的‘\’

string lw_qss = R"(
		QListWidget
		{
			/*border:1px solid gray;   �߽���:���ȡ���ɫ*/
			background:rgb(26, 26, 26);   /*���񱳾�ɫ*/
			color:rgb(200, 200, 200);     /*ǰ��ɫ��������ɫ*/
			font-size:15px;
			border-radius:1px;
		}
)

界面优化(m_pListWidget->setFocusPolicy(Qt::NoFocus);)

img
左边是QListWidget右边是QScrollArea
可以解决点击控件出现的不一致问题

QSCrollArea(主要做的是滚动窗口)

QScrollArea 是Qt框架中的一个控件,用于在用户界面中创建可滚动的区域。它通常用于显示包含较多内容的小部件,以便用户可以通过滚动条或其他滚动手势来查看不同部分的内容。以下是关于 QScrollArea 的一些重要概念和功能的解释:

  • 滚动区域 (Viewport): QScrollArea 包含一个称为滚动区域的部分,这是用于显示内容的可视区域。滚动区域通常是一个小部件,例如 QWidget 的子类。

  • 滚动条 (Scroll Bars): 如果滚动区域的内容大于可视区域,QScrollArea 会自动显示垂直和/或水平滚动条,以便用户可以滚动查看不同的内容。

  • 小部件设置 (Widget Setting): 通过 setWidget 方法,可以将要在滚动区域中显示的小部件设置为 QScrollArea 的子部件。这个小部件会自动成为滚动区域的内容,并且如果其大小超过可视区域,滚动条就会出现。

  • 自适应调整大小 (Automatic Resizing): 当设置了滚动区域的内容后,QScrollArea 会自动调整大小,以适应内容的大小。你也可以通过 setWidgetResizable 方法来控制是否允许滚动区域的大小随内容的改变而自动调整。

  • 滚动到指定位置 (Scrolling to a Position): 通过 verticalScrollBar 和 horizontalScrollBar 方法,可以获取垂直和水平滚动条的引用,并通过调用它们的方法来手动控制滚动区域的滚动位置。

  • 边缘控制 (Border Control): QScrollArea 还提供了一些方法,如 setWidgetResizable、setAlignment 等,用于控制滚动区域中小部件的对齐方式、大小调整等。

示例代码

  //第一部分创建QScrollArea
  m_pScrollArea = new QScrollArea(this);
    m_pScrollArea->setFixedWidth(1000 + 30);
	m_pScrollArea->setFrameShape(QFrame::NoFrame);
	m_pScrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); 
	m_pScrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);   
     

    //第二部分使用一个vector容器去装需要的widgets
	m_pBaseSetWidget = new CBaseSetWidget;
	m_vecWidget.push_back(m_pBaseSetWidget);

	m_pYunpanSetWidget = new QWidget;
	m_pYunpanSetWidget->setStyleSheet("background-image:url(:/ScrollAreaDemo/resources/YunPanSet.png);background-repeat: no-repeat;background-color:rgb(51, 51, 51)");
	m_pYunpanSetWidget->setFixedSize(1000, 478);
	m_vecWidget.push_back(m_pYunpanSetWidget);
    // 这里主要是使用一个widget把上面所有的widgets全部装入到这个容器里面
		QWidget* widget = new QWidget;

	QVBoxLayout* pVLay = new QVBoxLayout(widget);


	for (auto w : m_vecWidget)
	{
		pVLay->addWidget(w);
		pVLay->addSpacing(15);
	}
   
  //第三部分,配合之前的QListWidget,使得点击左边的item,右边的scrollarea就自动跳到相应位置
   connect(m_pListWidget, &QListWidget::itemClicked, this, &ScrollAreaDemo::slotItemClicked);
	
void ScrollAreaDemo::slotItemClicked(QListWidgetItem* item)
{
	signFlag = true;
	QString itemText = item->text();
	QPoint widgetPos;

	int size = m_textList.size();
	for (int i = 0; i < size; i++)
	{
		if (itemText == m_textList[i])
		{
			widgetPos = m_vecWidget[i]->pos();
		}
	}

	m_pScrollArea->verticalScrollBar()->setValue(widgetPos.y());
}
posted @   NoAcalculia  阅读(389)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示