【源码放送】Python制作TIM登录界面完整源码

本源码来自于州的先生基于 Python 的 PyQt5 库制作的新版 TIM 登录界面。

有关具体的代码实现思路和方式,详见下面的文章:

除了还原 TIM 登录界面样式之外,还实现了如下的交互:

  • QQ/微信登录方式切换;
  • 二维码扫码登陆切换;
  • 用户名密码输入;

这份源码一共包含 1 个 Python 文件、1 个 JPG 图片文件和 15 个 svg 图片文件:

引入的模块

# coding:utf-8 # @文件: pyqt_tim_login_gui.py # @创建者:州的先生 # #日期:2020/9/17 # 博客地址:zmister.com # 公众号:zmister2016  from PyQt5 import QtWidgets,QtCore,QtGui import sys import qrcode import io 

主窗口类

class TimLogin(QtWidgets.QMainWindow):     def __init__(self):         super().__init__()         self.setFixedSize(680,520)          self.setObjectName('body')         self.setStyleSheet('''             QMainWindow#body{                 background-color:white;             }             QToolButton,QPushButton{                 border:none;             }             QPushButton:hover{                 color:#333;             }             QCheckBox::indicator {                 border: 1px solid #9FA3A9;              }             QWidget#acount_group,#pwd_gourp{                 border-bottom:1px solid #E0E0E0;             }             QCheckBox,QLabel{                 color:#9FA3A9;             }             QToolButton#wx_icon{                 color:#9FA3A9;             }             QToolButton#wx_icon:hover{                 color:#1ABB0E;             }              QToolButton#qq_icon{                 color:#378AFE;             }             QToolButton#qq_icon:hover{                 color:#378AFE;             }              QPushButton#setting_icon{                 border-image: url("./setting.svg");             }              QPushButton#setting_icon:hover {                 border-image: url("./setting_hover.svg");             }              QPushButton#close_icon{                 border-image: url("./close.svg");             }             QPushButton#close_icon:hover {                 border-image: url("./close_hover.svg");             }              QPushButton#acount_icon{                 border-image: url("./lower.svg");             }             QPushButton#acount_icon:hover {                 border-image: url("./lower_hover.svg");             }              QPushButton#forward_icon{                 border-image: url("./forward.svg");             }             QPushButton#forward_icon:hover {                 border-image: url("./forward_hover.svg");             }              QPushButton#qrcode_icon{                 border-image: url("./qrcode.svg");             }             QPushButton#qrcode_icon:hover {                 border-image: url("./qrcode_hover.svg");             }              QPushButton#close_icon{                 border-image: url("./close.svg");             }             QPushButton#close_icon:hover {                 border-image: url("./close_hover.svg");             }         ''')         self.current_login = 'qq'         # 主控件         self.main_widget = QtWidgets.QWidget()         # 主布局         self.main_layout = QtWidgets.QGridLayout()         self.main_layout.setContentsMargins(0,0,0,0)         self.main_widget.setLayout(self.main_layout)          # 左侧背景控件         self.left_widget = QtWidgets.QWidget()         self.left_widget.setStyleSheet('''             background-image:url(./bg.jpg)         ''')           # 顶部控制按钮组         self.top_btn_group = QtWidgets.QWidget()         self.top_btn_group_layout = QtWidgets.QHBoxLayout()         self.top_btn_group_layout.setAlignment(QtCore.Qt.AlignTop|QtCore.Qt.AlignRight) # 联合顶部对齐和右对齐         self.top_btn_group.setLayout(self.top_btn_group_layout)          self.top_setting_btn = QtWidgets.QPushButton()         self.top_setting_btn.setObjectName('setting_icon')         # self.top_setting_btn.setIcon(QtGui.QIcon('./setting.svg'))         self.top_setting_btn.setFixedSize(20,20)         self.top_setting_btn.setIconSize(QtCore.QSize(20,20))         self.top_setting_btn.setToolTip("设置")          self.top_close_btn = QtWidgets.QPushButton()         self.top_close_btn.setObjectName('close_icon')         # self.top_close_btn.setIcon(QtGui.QIcon('./close.svg'))         self.top_close_btn.setFixedSize(20,20)         self.top_close_btn.setIconSize(QtCore.QSize(20,20))         self.top_close_btn.setToolTip("关闭")         self.top_close_btn.clicked.connect(self.close_btn_slot)          # self.top_setting_btn.installEventFilter(self)         self.top_btn_group_layout.addWidget(self.top_setting_btn)         self.top_btn_group_layout.addWidget(self.top_close_btn)          # QQ 图标按钮         self.qq_icon = QtWidgets.QToolButton()         self.qq_icon.setObjectName('qq_icon')         self.qq_icon.setText("QQ 登录")         self.qq_icon.setIcon(QtGui.QIcon("./qq_hover.svg"))         self.qq_icon.setIconSize(QtCore.QSize(60,60))         self.qq_icon.setToolButtonStyle(QtCore.Qt.ToolButtonTextUnderIcon)         self.qq_icon.clicked.connect(self.switch_to_qq_login)         self.qq_icon.installEventFilter(self)           # 微信图标按钮         self.wx_icon = QtWidgets.QToolButton()         self.wx_icon.setObjectName('wx_icon')         self.wx_icon.setText("微信登录")         self.wx_icon.setIcon(QtGui.QIcon("./wx.svg"))         self.wx_icon.setIconSize(QtCore.QSize(60, 60))         self.wx_icon.setToolButtonStyle(QtCore.Qt.ToolButtonTextUnderIcon)         self.wx_icon.installEventFilter(self)         self.wx_icon.clicked.connect(self.switch_to_wx_login)          # 图标按钮组         self.icon_btn_group = QtWidgets.QWidget()         self.icon_btn_group_layout = QtWidgets.QHBoxLayout()         self.icon_btn_group.setLayout(self.icon_btn_group_layout)         self.icon_btn_group_layout.addWidget(self.qq_icon)         self.icon_btn_group_layout.addWidget(self.wx_icon)          # 微信二维码扫码登陆         self.wx_qrcode = QtWidgets.QLabel()         self.wx_qrcode.setObjectName('wx_qrcode')         self.genera_qrcode()         self.wx_qrcode.setContentsMargins(8,5,0,10)         self.wx_qrcode_label = QtWidgets.QLabel("请使用微信扫描二维码登录")         self.wx_qrcode_group = QtWidgets.QWidget()         self.wx_qrcode_group.setContentsMargins(0,0,0,100)         self.wx_qrcode_group.setFixedHeight(313)         self.wx_qrcode_group_layout = QtWidgets.QVBoxLayout()         self.wx_qrcode_group_layout.setAlignment(QtCore.Qt.AlignCenter)         self.wx_qrcode_group.setLayout(self.wx_qrcode_group_layout)         self.wx_qrcode_group_layout.addWidget(self.wx_qrcode)         self.wx_qrcode_group_layout.addWidget(self.wx_qrcode_label)          # 表单输入         self.acount_input = QtWidgets.QLineEdit()         font = self.acount_input.font()         font.setPointSize(16)         self.acount_input.setFont(font)         self.acount_input.setStyleSheet('''             border: dashed 1px #9FA3A9;         ''')         self.acount_icon = QtWidgets.QPushButton()         self.acount_icon.setObjectName('acount_icon')         # self.acount_icon.setIcon(QtGui.QIcon('./lower.svg'))         self.acount_icon.setIconSize(QtCore.QSize(20,20))         self.acount_icon.setFixedSize(20,20)          self.acount_gourp = QtWidgets.QWidget()         self.acount_gourp.setObjectName('acount_group')         self.acount_gourp_layout = QtWidgets.QHBoxLayout()         self.acount_gourp.setLayout(self.acount_gourp_layout)         self.acount_gourp_layout.addWidget(self.acount_input)         self.acount_gourp_layout.addWidget(self.acount_icon)          self.pwd_input = QtWidgets.QLineEdit()         self.pwd_input.setEchoMode(QtWidgets.QLineEdit.Password)         self.pwd_input.setFont(font)         self.pwd_input.setStyleSheet('''             border: dashed 1px #9FA3A9;         ''')         self.pwd_icon = QtWidgets.QPushButton()         self.pwd_icon.setObjectName('forward_icon')         self.pwd_icon.setIconSize(QtCore.QSize(20, 20))         self.pwd_icon.setFixedSize(20,20)          self.pwd_gourp = QtWidgets.QWidget()         self.pwd_gourp.setObjectName('pwd_gourp')         self.pwd_gourp_layout = QtWidgets.QHBoxLayout()         self.pwd_gourp.setLayout(self.pwd_gourp_layout)         self.pwd_gourp_layout.addWidget(self.pwd_input)         self.pwd_gourp_layout.addWidget(self.pwd_icon)          self.qrcode_icon = QtWidgets.QPushButton()         self.qrcode_icon.setObjectName('qrcode_icon')         self.qrcode_icon.setIconSize(QtCore.QSize(16, 16))         self.qrcode_icon.setFixedSize(16, 16)         self.qrcode_widget = QtWidgets.QWidget()         self.qrcode_widget_layout = QtWidgets.QHBoxLayout()         self.qrcode_widget_layout.setAlignment(QtCore.Qt.AlignRight)         self.qrcode_widget.setLayout(self.qrcode_widget_layout)         self.qrcode_widget_layout.addWidget(self.qrcode_icon)         self.qrcode_icon.clicked.connect(self.switch_to_tim_qrcode_login)          self.form_group = QtWidgets.QWidget()         self.form_group_layout = QtWidgets.QVBoxLayout()         self.form_group.setLayout(self.form_group_layout)         self.form_group_layout.addWidget(self.acount_gourp)         self.form_group_layout.addWidget(self.pwd_gourp)         self.form_group_layout.addWidget(self.qrcode_widget)           # 选项         self.option_group = QtWidgets.QWidget()         self.option_group_layout = QtWidgets.QGridLayout()         self.option_group_layout.setContentsMargins(50,0,0,0)         self.option_group.setLayout(self.option_group_layout)         # 记住密码         self.remunber_pwd = QtWidgets.QCheckBox("记住密码")         self.find_pwd = QtWidgets.QLabel("找回密码")         self.auto_login = QtWidgets.QCheckBox("自动登录")         self.register = QtWidgets.QLabel("注册账号")         self.option_group_layout.addWidget(self.remunber_pwd,0,0,1,1)         self.option_group_layout.addWidget(self.find_pwd,0,1,1,1)         self.option_group_layout.addWidget(self.auto_login,1,0,1,1)         self.option_group_layout.addWidget(self.register,1,1,1,1)          # 右侧表单控件         self.right_widget = QtWidgets.QWidget()         self.right_layout = QtWidgets.QGridLayout()         self.right_widget.setLayout(self.right_layout)         self.right_layout.addWidget(self.top_btn_group,0,0,1,2)         self.right_layout.addWidget(self.icon_btn_group,1,0,1,2)         self.right_layout.addWidget(self.form_group,2,0,1,2)         self.right_layout.addWidget(self.option_group,3,0,2,2)          # 右侧 TIm 二维码控件 - 初始隐藏         self.right_qrcode_ui()          # 添加到主布局层         self.main_layout.addWidget(self.left_widget,0,0,5,3) #         self.main_layout.addWidget(self.right_widget,0,3,5,2)         self.main_layout.setSpacing(0)  # 设置网格布局层中部件的间隙          self.setCentralWidget(self.main_widget)         self.setWindowFlag(QtCore.Qt.FramelessWindowHint)      def right_qrcode_ui(self):         # 顶部控制按钮组         self.control_btn_group = QtWidgets.QWidget()         self.control_btn_group_layout = QtWidgets.QHBoxLayout()         self.control_btn_group_layout.setAlignment(QtCore.Qt.AlignTop | QtCore.Qt.AlignRight)  # 联合顶部对齐和右对齐         self.control_btn_group.setLayout(self.control_btn_group_layout)          self.control_back_btn = QtWidgets.QPushButton()         self.control_back_btn.setIcon(QtGui.QIcon('./back.svg'))         self.control_back_btn.setFixedSize(20,20)         self.control_back_btn.setIconSize(QtCore.QSize(20,20))         self.control_back_btn.setToolTip('返回')         self.control_back_btn.clicked.connect(self.switch_to_normal_login)          self.control_setting_btn = QtWidgets.QPushButton()         self.control_setting_btn.setObjectName('setting_icon')         self.control_setting_btn.setFixedSize(20, 20)         self.control_setting_btn.setIconSize(QtCore.QSize(20, 20))         self.control_setting_btn.setToolTip("设置")          self.control_close_btn = QtWidgets.QPushButton()         self.control_close_btn.setObjectName('close_icon')         self.control_close_btn.setFixedSize(20, 20)         self.control_close_btn.setIconSize(QtCore.QSize(20, 20))         self.control_close_btn.setToolTip("关闭")         self.control_close_btn.clicked.connect(self.close_btn_slot)          self.control_btn_group_layout.addWidget(self.control_back_btn)         self.control_btn_group_layout.addWidget(self.control_setting_btn)         self.control_btn_group_layout.addWidget(self.control_close_btn)          # 二维码         self.tim_qrcode = QtWidgets.QLabel()         self.tim_qrcode.setObjectName('wx_qrcode')         self.tim_qrcode.setPixmap(self.genera_qrcode())         self.tim_qrcode.setContentsMargins(8, 5, 0, 10)         self.tim_qrcode_label = QtWidgets.QLabel("用 <a href='https://office.qq.com/'>TIM 手机版 </a> 扫描二维码登录")         self.tim_qrcode_label.setOpenExternalLinks(True)         self.tim_qrcode_group = QtWidgets.QWidget()         self.tim_qrcode_group.setContentsMargins(0, 0, 0, 100)         self.tim_qrcode_group.setFixedHeight(300)         self.tim_qrcode_group_layout = QtWidgets.QVBoxLayout()         self.tim_qrcode_group_layout.setAlignment(QtCore.Qt.AlignCenter)         self.tim_qrcode_group.setLayout(self.tim_qrcode_group_layout)         self.tim_qrcode_group_layout.addWidget(self.tim_qrcode)         self.tim_qrcode_group_layout.addWidget(self.tim_qrcode_label)          self.right_qrcode_widget = QtWidgets.QWidget()         self.right_qrcode_widget_layout = QtWidgets.QGridLayout()         self.right_qrcode_widget.setLayout(self.right_qrcode_widget_layout)         self.right_qrcode_widget_layout.addWidget(self.control_btn_group)         self.right_qrcode_widget_layout.addWidget(self.tim_qrcode_group)       # 窗口关闭信号     def close_btn_slot(self):         # self.close()         self.parent().close()      # 事件过滤器     def eventFilter(self, QObject, QEvent):         # print(QObject)         # 修改微信图标         if QObject is self.wx_icon:             if self.current_login == 'qq':                 if QEvent.type() == QtCore.QEvent.HoverEnter:                     self.wx_icon.setIcon(QtGui.QIcon('./wx_hover.svg'))                 elif QEvent.type() == QtCore.QEvent.HoverLeave:                     self.wx_icon.setIcon(QtGui.QIcon('./wx.svg'))          if QObject is self.qq_icon:             if self.current_login == 'wx':                 if QEvent.type() == QtCore.QEvent.HoverEnter:                     self.qq_icon.setIcon(QtGui.QIcon('./qq_hover.svg'))                 elif QEvent.type() == QtCore.QEvent.HoverLeave:                     self.qq_icon.setIcon(QtGui.QIcon('./qq.svg'))           return False      # 切换到微信登录     def switch_to_wx_login(self):         if self.current_login == 'qq':             # 移除表单和选项控件             self.right_layout.removeWidget(self.form_group)             self.right_layout.removeWidget(self.option_group)             self.form_group.hide()             self.option_group.hide()             # 添加二维码控件             self.right_layout.addWidget(self.wx_qrcode_group,2,0,3,2)             self.wx_qrcode_group.show()             # 设置微信图标状态             self.wx_icon.setIcon(QtGui.QIcon('./wx_hover.svg'))             self.current_login = 'wx'             # 设置 QQ 图标状态             self.qq_icon.setIcon(QtGui.QIcon('./qq.svg'))             self.wx_icon.setStyleSheet('''             QToolButton#wx_icon{                 color:#1ABB0E;             }             QToolButton#wx_icon:hover{                 color:#1ABB0E;             }               ''')             self.qq_icon.setStyleSheet('''             QToolButton#qq_icon{                 color:#9FA3A9;             }             QToolButton#qq_icon:hover{                 color:#378AFE;             }             ''')      # 切换到 QQ 登录     def switch_to_qq_login(self):         if self.current_login == 'wx':             # 移除二维码控件             self.right_layout.removeWidget(self.wx_qrcode_group)             self.wx_qrcode_group.hide()             # 添加表单控件             self.right_layout.addWidget(self.form_group, 2, 0, 1, 2)             self.right_layout.addWidget(self.option_group,3,0,2,2)             self.option_group.show()             self.form_group.show()             # 设置微信图标状态             self.wx_icon.setIcon(QtGui.QIcon('./wx.svg'))             self.current_login = 'qq'             # 设置 QQ 图标状态             self.qq_icon.setIcon(QtGui.QIcon('./qq_hover.svg'))              self.wx_icon.setStyleSheet('''                         QToolButton#wx_icon{                             color:#9FA3A9;                         }                         QToolButton#wx_icon:hover{                             color:#1ABB0E;                         }                           ''')             self.qq_icon.setStyleSheet('''                         QToolButton#qq_icon{                             color:#378AFE;                         }                         QToolButton#qq_icon:hover{                             color:#378AFE;                         }                         ''')       # 切换到 TIM 手机扫码登陆     def switch_to_tim_qrcode_login(self):         # 移除右侧控件         self.main_layout.removeWidget(self.right_widget)         self.right_widget.hide()         # 添加 TIM 扫码登陆控件         self.main_layout.addWidget(self.right_qrcode_widget,0,3,5,2)         self.right_qrcode_widget.show()      # 切换到常规登录     def switch_to_normal_login(self):         # 移除右侧控件         self.main_layout.removeWidget(self.right_qrcode_widget)         self.right_qrcode_widget.hide()         # 添加常规登录控件         self.main_layout.addWidget(self.right_widget,0,3,5,2)         self.right_widget.show()      # 生成一个二维码     def genera_qrcode(self,qr_text="https://zmister.com"):         qr = qrcode.QRCode(             version=1,             box_size=5,             border=0         )         qr.add_data(qr_text)         self.qr_img = qr.make_image()          fp = io.BytesIO()         self.qr_img.save(fp, "BMP")         image = QtGui.QImage()         image.loadFromData(fp.getvalue(), "BMP")         qr_pixmap = QtGui.QPixmap.fromImage(image)         self.wx_qrcode.setPixmap(qr_pixmap)         return qr_pixmap 

容器类

class Container(QtWidgets.QWidget):     def __init__(self, window):         super().__init__()         self.setWindowFlags(QtCore.Qt.FramelessWindowHint)         self.setAttribute(QtCore.Qt.WA_TranslucentBackground)         lay = QtWidgets.QVBoxLayout(self)         lay.addWidget(window)         lay.setContentsMargins(10, 10, 10, 10)         shadow = QtWidgets.QGraphicsDropShadowEffect(self,             blurRadius=9.0,             color=QtGui.QColor(116, 116, 116),             offset=QtCore.QPointF(0, 0)         )         window.setGraphicsEffect(shadow)      # 重写三个方法使我们的窗口支持拖动,上面参数 window 就是拖动对象     def mousePressEvent(self, event):  # 鼠标长按事件         if event.button() == QtCore.Qt.LeftButton:             self.m_drag = True             self.m_DragPosition = event.globalPos() - self.pos()             event.accept()             self.setCursor(QtGui.QCursor(QtCore.Qt.OpenHandCursor))      def mouseMoveEvent(self, QMouseEvent):  # 鼠标移动事件         if QtCore.Qt.LeftButton and self.m_drag:             self.move(QMouseEvent.globalPos() - self.m_DragPosition)             QMouseEvent.accept()      def mouseReleaseEvent(self, QMouseEvent):  # 鼠标释放事件         self.m_drag = False         self.setCursor(QtGui.QCursor(QtCore.Qt.ArrowCursor)) 

运行方法

def main():     app = QtWidgets.QApplication(sys.argv)     gui = TimLogin()     container = Container(gui)     container.show()     sys.exit(app.exec_())  if __name__ == '__main__':     main() 

资源图片

州的先生微信公众号回复“0022”获取所需的图片文件资源。

分类目录: 图形用户界面