博客
关于我
python 导航栏
阅读量:359 次
发布时间:2019-03-04

本文共 5527 字,大约阅读时间需要 18 分钟。

导航条控件实现

以下是基于PyQt4的导航条控件实现代码的详细解析

导航条控件类(NavigationWidget)

导航条控件是一个用于显示多个选项并支持交互操作的组件。本类通过继承QWidget类实现,并集成了以下功能:

1. 类结构
class NavigationWidget(QWidget):
currentItemChanged = pyqtSignal([int, str]) # 信号,传递当前选项索引和内容
  • 信号定义currentItemChanged 用于传递当前选项的索引和内容,可以在主窗口中连接相应的槽函数
  • 继承自QWidget
2. 初始化
def __init__(self, parent=None):
super(NavigationWidget, self).__init__(parent)
self.initUI()
  • 初始化方法initUI() 用于初始化UI布局和颜色设置
  • 初始属性
    • self.backgroundColor = '#E4E4E4':导航条背景颜色
    • self.selectedColor = '#2CA7F8':当前选项的颜色
    • self.rowHeight = 40:每行的高度
    • self.currentIndex = 0:当前选项的索引
    • self.listItems = []:存储导航条选项
    • self.cursorIndex = -1:光标所在位置的选项索引
    • self.setMouseTracking(True):启用鼠标追踪
    • self.setMinimumWidth(120):最小宽度设定
3. 添加选项
def addItem(self, item):
self.listItems.append(item)
self.update()
  • 功能:添加新的选项到导航条中
  • 实现:将选项添加到列表中,并调用update()方法刷新UI显示
  • 参数item:要添加的选项内容
4. 设置选项
def setItems(self, items):
self.listItems = items
self.update()
  • 功能:设置导航条的所有选项
  • 实现:将传入的选项列表赋值给self.listItems,并刷新UI显示
  • 参数items:新的选项列表
5. 设置颜色
def setBackgroundColor(self, color):
self.backgroundColor = color
self.update()
def setSelectColor(self, color):
self.selectedColor = color
self.update()
  • 功能:设置导航条的背景颜色或选项选中的颜色
  • 实现:直接修改对应的颜色属性并刷新UI
  • 参数color:颜色值( HEX 格式)
6. 设置行高
def setRowHeight(self, height):
self.rowHeight = height
self.update()
  • 功能:设置导航条每行的高度
  • 实现:修改self.rowHeight属性并刷新UI显示
  • 参数height:行高值(像素)
7. 设置当前选项
def setCurrentIndex(self, idx):
self.currentIndex = idx
self.currentItemChanged.emit(idx, self.listItems[idx])
self.update()
  • 功能:设置当前选中的选项
  • 实现
    • 修改currentIndex属性
    • 发射信号,传递当前索引和选项内容
    • 刷新UI显示
  • 参数idx:选项的索引值
8. 画布事件
def paintEvent(self, evt):
painter = QPainter(self)
painter.setRenderHint(QPainter.Antialiasing, True) # 设置抗锯齿绘制
# 画背景色
painter.setPen(Qt.NoPen)
painter.setBrush(QColor(self.backgroundColor))
painter.drawRect(self.rect())
# 画子项
for i in range(len(self.listItems)):
itemPath = QPainterPath()
itemPath.addRect(QRectF(0, i * self.rowHeight, self.width() - 1, self.rowHeight - 1))
if i == self.currentIndex:
# 当前选项
painter.setPen(QColor('#FFFFFF'))
painter.fillPath(itemPath, QColor(self.selectedColor))
elif i == self.cursorIndex:
# 光标所在位置
painter.setPen(QColor('#FFFFFF'))
painter.fillPath(itemPath, QColor(self.selectedColor))
else:
# 其他选项
painter.setPen(QColor('#202020'))
painter.fillPath(itemPath, QColor(self.backgroundColor))
# 绘制文字
painter.drawText(
QRect(0, i * self.rowHeight, self.width(), self.rowHeight),
Qt.AlignVCenter | Qt.AlignHCenter,
self.listItems[i]
)
  • 实现:通过QPainter绘制导航条背景和各选项
  • 绘制逻辑
    • 遍历选项列表,绘制每个选项的矩形区域
    • 根据当前索引和光标位置设置颜色
    • 在矩形中间绘制选项文字
  • 样式
    • 非选中状态:白色边框,背景为#202020
    • 选中状态:白色边框,背景为#2CA7F8
    • 光标所在位置:白色边框,背景为#2CA7F8
9. 鼓励事件
def mouseMoveEvent(self, evt):
idx = evt.y() / self.rowHeight # 计算光标在导航条上的位置索引
if idx >= len(self.listItems):
idx = -1 # 超出范围则设置为-1
if idx < len(self.listItems) and idx != self.cursorIndex:
self.update() # 刷新UI
self.cursorIndex = idx # 更新光标索引
  • 功能:鼠标在导航条上移动时,更新光标所在位置
  • 实现
    • 计算光标纵坐标相对于行高的索引
    • 判断索引是否超出范围(设置为-1)
    • 判断当前索引是否与光标索引相同(如果不同,则更新)
    • 刷新UI并更新光标索引
10. 点击事件
def mousePressEvent(self, evt):
idx = evt.y() / self.rowHeight # 计算点击位置的索引
if idx < len(self.listItems):
self.currentIndex = idx # 设置当前选项索引
self.currentItemChanged.emit(idx, self.listItems[idx]) # 发射信号
self.update() # 刷新UI
  • 功能:导航条项的点击事件处理
  • 实现
    • 计算点击位置的索引
    • 判断索引是否有效
    • 设置当前选项索引
    • 发射信号,传递当前选项索引和内容
    • 刷新UI显示
11. 离开事件
def leaveEvent(self, QEvent):
self.cursorIndex = -1 # 光标离开时重置索引
self.update() # 刷新UI
  • 功能:鼠标从导航条上离开时的处理
  • 实现
    • 重置光标索引为-1
    • 刷新UI显示

主窗口(MainWindow)

class MainWindow(QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.initUI()
def initUI(self):
self.resize(600, 400) # 窗口大小
self.setWindowTitle(u'导航条控件') # 窗口标题
mainWidget = QWidget() # 中央布局容器
self.setCentralWidget(mainWidget)
# 创建导航条控件
navigationWidget = NavigationWidget()
navigationWidget.setRowHeight(50) # 行高设定
navigationWidget.setItems([u'常规', u'高级', u'管理', u'其其他', u'关于']) # 设置导航条选项
self.tipsLabel = QLabel(u"请选择:") # 提示标签
# 主布局
mainLayout = QHBoxLayout(mainWidget)
mainLayout.setContentsMargins(0, 0, 0, 0) # 去除外部间距
mainLayout.setSpacing(10) # 垂直间距
mainLayout.addWidget(navigationWidget, 1) # 左侧布局
mainLayout.addWidget(self.tipsLabel, 3, Qt.AlignCenter) # 右侧布局,居中对齐
# 信号连接
navigationWidget.currentItemChanged[int, str].connect(self.slotCurrentItemChanged) # 连接信号槽
navigationWidget.setCurrentIndex(2) # 初始化当前选项为第三个(索引从0开始)
self.show() # 显示主窗口
  • 功能:创建并配置主窗口,包含导航条控件和提示标签
  • 实现
    • 窗口大小和标题设定
    • 创建中央布局容器
    • 初始化导航条控件,设置行高和选项
    • 创建提示标签
    • 设置主布局
    • 连接导航条信号槽
    • 设置初始当前选项索引
    • 显示主窗口

主窗口槽函数

def slotCurrentItemChanged(self, index, content):
self.tipsLabel.setText(u"Current index and content:{} ---- {}".format(index, content))
  • 功能:接收导航条信号,显示当前选项索引和内容
  • 实现
    • 接收indexcontent参数
    • 将内容显示在提示标签中

运行主程序

def main():
app = QApplication(sys.argv) # 创建应用程序实例
mainWnd = MainWindow() # 创建主窗口实例
sys.exit(app.exec_()) # 应用程序主循环
  • 功能:启动PyQt4应用程序,创建并显示主窗口
  • 实现
    • 创建QApplication实例
    • 创建并显示MainWindow实例
    • 应用程序的主循环运行

运行结果

运行上述代码后,会显示一个600x400的主窗口,包含一个导航条控件和一个提示标签。导航条上有五个选项(常规、高级、管理、其它、关于),初始时选中“管理”选项。鼠标悬停或点击导航条项时,会显示相应的索引和内容。

总结

通过上述代码实现了一个功能丰富的导航条控件,支持选项的设置、颜色配置、鼠标交互等多种功能,并通过信号机制与主窗口进行数据传递,实现了良好的UI交互设计。

转载地址:http://orrr.baihongyu.com/

你可能感兴趣的文章
nmap指纹识别要点以及又快又准之方法
查看>>
Nmap渗透测试指南之指纹识别与探测、伺机而动
查看>>
Nmap端口扫描工具Windows安装和命令大全(非常详细)零基础入门到精通,收藏这篇就够了
查看>>
NMAP网络扫描工具的安装与使用
查看>>
NMF(非负矩阵分解)
查看>>
nmon_x86_64_centos7工具如何使用
查看>>
NN&DL4.1 Deep L-layer neural network简介
查看>>
NN&DL4.3 Getting your matrix dimensions right
查看>>
NN&DL4.7 Parameters vs Hyperparameters
查看>>
NN&DL4.8 What does this have to do with the brain?
查看>>
nnU-Net 终极指南
查看>>
No 'Access-Control-Allow-Origin' header is present on the requested resource.
查看>>
NO 157 去掉禅道访问地址中的zentao
查看>>
no available service ‘default‘ found, please make sure registry config corre seata
查看>>
No compiler is provided in this environment. Perhaps you are running on a JRE rather than a JDK?
查看>>
no connection could be made because the target machine actively refused it.问题解决
查看>>
No Datastore Session bound to thread, and configuration does not allow creation of non-transactional
查看>>
No fallbackFactory instance of type class com.ruoyi---SpringCloud Alibaba_若依微服务框架改造---工作笔记005
查看>>
No Feign Client for loadBalancing defined. Did you forget to include spring-cloud-starter-loadbalanc
查看>>
No mapping found for HTTP request with URI [/...] in DispatcherServlet with name ...的解决方法
查看>>