本文共 5527 字,大约阅读时间需要 18 分钟。
以下是基于PyQt4的导航条控件实现代码的详细解析
导航条控件是一个用于显示多个选项并支持交互操作的组件。本类通过继承QWidget类实现,并集成了以下功能:
class NavigationWidget(QWidget): currentItemChanged = pyqtSignal([int, str]) # 信号,传递当前选项索引和内容
currentItemChanged 用于传递当前选项的索引和内容,可以在主窗口中连接相应的槽函数QWidgetdef __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):最小宽度设定def addItem(self, item): self.listItems.append(item) self.update()
update()方法刷新UI显示item:要添加的选项内容def setItems(self, items): self.listItems = items self.update()
self.listItems,并刷新UI显示items:新的选项列表def setBackgroundColor(self, color): self.backgroundColor = color self.update()
def setSelectColor(self, color): self.selectedColor = color self.update()
color:颜色值( HEX 格式)def setRowHeight(self, height): self.rowHeight = height self.update()
self.rowHeight属性并刷新UI显示height:行高值(像素)def setCurrentIndex(self, idx): self.currentIndex = idx self.currentItemChanged.emit(idx, self.listItems[idx]) self.update()
currentIndex属性idx:选项的索引值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#2CA7F8def 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 # 更新光标索引
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
def leaveEvent(self, QEvent): self.cursorIndex = -1 # 光标离开时重置索引 self.update() # 刷新UI
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)) index和content参数def main(): app = QApplication(sys.argv) # 创建应用程序实例 mainWnd = MainWindow() # 创建主窗口实例 sys.exit(app.exec_()) # 应用程序主循环
QApplication实例MainWindow实例运行上述代码后,会显示一个600x400的主窗口,包含一个导航条控件和一个提示标签。导航条上有五个选项(常规、高级、管理、其它、关于),初始时选中“管理”选项。鼠标悬停或点击导航条项时,会显示相应的索引和内容。
通过上述代码实现了一个功能丰富的导航条控件,支持选项的设置、颜色配置、鼠标交互等多种功能,并通过信号机制与主窗口进行数据传递,实现了良好的UI交互设计。
转载地址:http://orrr.baihongyu.com/