Pyqt5

 hello&菜单&布局

#第一章
# Hello World

# 例1,简单的窗口
# import sys
# from PyQt5.QtWidgets import QApplication, QWidget


# if __name__ == '__main__':

#     app = QApplication(sys.argv)
#     '''
#     每个PyQt5应用都必须创建一个应用对象。sys.argv
#     是一组命令行参数的列表。Python可以在shell里运行
#     ,这个参数提供对脚本控制的功能
#     '''

#     # 这里开始写代码
#     w = QWidget()
#     w.resize(500, 300)
#     w.move(400, 250)
#     w.setWindowTitle('Simple')
#     w.show()
#     #

#     sys.exit(app.exec_())



# 例2,带窗口图标
# import sys
# from PyQt5.QtWidgets import QApplication, QWidget
# from PyQt5.QtGui import QIcon

# class Example(QWidget):

#     def __init__(self):
#         super().__init__()

#         self.initUI()


#     def initUI(self):

#         self.setGeometry(50, 100, 800, 500)
#         self.setWindowTitle('Icon')
#         # self.setWindowIcon(QIcon('Desktop/1.png')) 
#         #mac min 好像没有窗口图标,不显示    
#         self.show()

# if __name__ == '__main__':
#     app = QApplication(sys.argv)
#     ex = Example()
#     sys.exit(app.exec_())

# # 例6,带窗口图标
# '''
# setWindowIcon是QApplication的方法,而不是QWidget的,
# 所以使用app.setWindowIcon设置是对的。

# 注意:在mac下,图标是显示在程序坞中的!!!
# '''
import sys

from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import QApplication, QWidget


class Example(QWidget):

    def __init__(self):
        super().__init__()

        self.initUI()


    def initUI(self):

        self.setGeometry(220, 100, 400, 300)
        self.setWindowTitle('Icon')
        # self.setWindowIcon(QIcon('Desktop/3.png')) 
        
        #mac min 好像没有窗口图标,不显示    
        self.show()

if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = Example()
    app.setWindowIcon(QIcon('Desktop/3.png'))
    sys.exit(app.exec_())

# 例3,提示框
# import sys
# from PyQt5.QtWidgets import (QWidget, QToolTip, 
#     QPushButton, QApplication)
# from PyQt5.QtGui import QFont    

# class Example(QWidget):

#     def __init__(self):
#         super().__init__()

#         self.initUI()

#     def initUI(self):

#         QToolTip.setFont(QFont('SansSerif', 10))
#         # 设置了提示框的字体,我们使用了10px的SansSerif字体

#         self.setToolTip('This is a <b>QWidget</b> widget')
#         #mac没有提示框,所以不显示

#         btn = QPushButton('Button', self)
#         btn.setToolTip('This is a <b>QPushButton</b> widget')
#         btn.resize(btn.sizeHint())
#         # sizeHint()方法提供了一个默认的按钮大小
#         btn.move(50, 50)       

#         self.setGeometry(300, 300, 300, 200)
#         self.setWindowTitle('Tooltips')    
#         self.show()

# if __name__ == '__main__':
#     app = QApplication(sys.argv)
#     ex = Example()
#     sys.exit(app.exec_())



# 例4,关闭窗口
# import sys
# from PyQt5.QtWidgets import QWidget, QPushButton, QApplication
# from PyQt5.QtCore import QCoreApplication


# class Example(QWidget):

#     def __init__(self):
#         super().__init__()

#         self.initUI()


#     def initUI(self):               

#         qbtn = QPushButton('Quit', self)
#         qbtn.clicked.connect(QCoreApplication.instance().quit)
#         qbtn.resize(qbtn.sizeHint())
#         # sizeHint()方法提供了一个默认的按钮大小
#         qbtn.move(50, 50)       

#         self.setGeometry(300, 300, 250, 150)
#         self.setWindowTitle('Quit button')    
#         self.show()


# if __name__ == '__main__':

#     app = QApplication(sys.argv)
#     ex = Example()
#     sys.exit(app.exec_())




# 例5,消息盒子
# import sys
# from PyQt5.QtWidgets import QWidget, QMessageBox, QApplication

# class Example(QWidget):

#     def __init__(self):
#         super().__init__()

#         self.initUI()


#     def initUI(self):               

#         self.setGeometry(300, 300, 250, 150)        
#         self.setWindowTitle('Message box')    
#         self.show()


#     def closeEvent(self, event):
#         #mac中message没有显示在消息框的标题栏
#         reply = QMessageBox.question(self, 'Message',
#             "Are you sure to quit?", QMessageBox.Yes | 
#             QMessageBox.No, QMessageBox.No)

#         if reply == QMessageBox.Yes:
#             event.accept()
#         else:
#             event.ignore()        

# if __name__ == '__main__':

#     app = QApplication(sys.argv)
#     ex = Example()
#     sys.exit(app.exec_())



# 例6,窗口居中

# import sys
# from PyQt5.QtWidgets import QWidget, QDesktopWidget, QApplication
# # QtGui.QDesktopWidget提供了用户的桌面信息,包括屏幕的大小

# class Example(QWidget):

#     def __init__(self):
#         super().__init__()

#         self.initUI()


#     def initUI(self):               

#         self.resize(250, 150)
#         self.center()

#         self.setWindowTitle('Center')    
#         self.show()


#     def center(self):

#         qr = self.frameGeometry()
#         # 获得主窗口所在的框架
#         cp = QDesktopWidget().availableGeometry().center()
#         # 获取显示器的分辨率,然后得到屏幕中间点的位置
#         qr.moveCenter(cp)
#         # 把主窗口框架的中心点放置到屏幕的中心位置
#         self.move(qr.topLeft())
#         # 通过move函数把主窗口的左上角移动到其框架的左上角,这样就把窗口居中了


# if __name__ == '__main__':
#     app = QApplication(sys.argv)
#     ex = Example()
#     sys.exit(app.exec_())

#第二章
# 菜单和工具栏

'''
这个章节,我们会创建状态栏、菜单和工具栏。菜单是一组位于菜单栏的命令。
工具栏是应用的一些常用工具按钮。状态栏显示一些状态信息,通常在应用的底部。
'''

# 状态栏
'''
主窗口
QMainWindow提供了主窗口的功能,使用它能创建一些简单的状态栏、工具栏和菜单栏
'''
# import sys
# from PyQt5.QtWidgets import QMainWindow, QApplication

# class Example(QMainWindow):

#     def __init__(self):
#         super().__init__()

#         self.initUI()


#     def initUI(self):               

#         self.statusBar().showMessage('这是状态栏')

#         self.setGeometry(300, 300, 250, 150)
#         self.setWindowTitle('Statusbar')    
#         self.show()

# if __name__ == '__main__':
#     app = QApplication(sys.argv)
#     ex = Example()
#     sys.exit(app.exec_())




# 菜单栏
# 菜单栏是非常常用的。是一组命令的集合(Mac OS下状态栏的显示不一样,
# 为得到最相似的外观,我们可以增加一行语句menubar.setNativeMenuBar(False))
# import sys
# from PyQt5.QtWidgets import QMainWindow, QAction, qApp, QApplication
# from PyQt5.QtGui import QIcon

# class Example(QMainWindow):

#     def __init__(self):
#         super().__init__()

#         self.initUI()

#     def initUI(self):               

#         exitAct = QAction(QIcon('1.png'), '&Exit', self)        
#         exitAct.setShortcut('Ctrl+Q')#快捷键
#         exitAct.setStatusTip('Exit application')
#         '''
#         QAction是菜单栏、工具栏或者快捷键的动作的组合。
#         上面三行中,前两行创建了一个图标、一个exit的
#         标签和一个快捷键组合,都执行了一个动作;第三行,
#         创建了一个状态栏,当鼠标悬停在菜单栏的时候,能显示当前状态
#         '''
#         exitAct.triggered.connect(qApp.quit)
#         # 当执行这个指定的动作时,就触发了一个事件。这个事件
#         # 跟QApplication的quit()行为相关联,所以这个动作就能终止这个应用

#         self.statusBar()

#         menubar = self.menuBar()
#         menubar.setNativeMenuBar(False)
#         fileMenu = menubar.addMenu('&File')

#         fileMenu.addAction(exitAct)
#         # # menuBar()创建菜单栏。这里创建了一个菜单栏,并用addMenu()
#         # # 在上面添加了一个file菜单,用addAction()关联了点击退出应用的事件

#         self.setGeometry(300, 300, 300, 200)
#         self.setWindowTitle('Simple menu')    
#         self.show()


# if __name__ == '__main__':

#     app = QApplication(sys.argv)
#     ex = Example()
#     sys.exit(app.exec_())



# 重要 重要 重要
# 子菜单
# import sys
# from PyQt5.QtWidgets import QMainWindow, QAction, QMenu, QApplication

# class Example(QMainWindow):

#     def __init__(self):
#         super().__init__()

#         self.initUI()


#     def initUI(self):         

#         menubar = self.menuBar()
#         menubar.setNativeMenuBar(False)
#         fileMenu = menubar.addMenu('File')#菜单名

#         impMenu = QMenu('Import', self)
#         impAct = QAction('Import mail', self) 
#         impAct.setStatusTip('Import mail application') 
#         impMenu.addAction(impAct)

#         newAct = QAction('New', self)  
#         newAct.setStatusTip('new application')      

#         fileMenu.addAction(newAct)
#         fileMenu.addMenu(impMenu)

#         self.statusBar()

#         self.setGeometry(300, 300, 300, 200)
#         self.setWindowTitle('Submenu')    
#         self.show()

# if __name__ == '__main__':
#     app = QApplication(sys.argv)
#     ex = Example()
#     sys.exit(app.exec_())


# 勾选菜单
# import sys
# from PyQt5.QtWidgets import QMainWindow, QAction, QApplication, qApp

# class Example(QMainWindow):

#     def __init__(self):
#         super().__init__()

#         self.initUI()


#     def initUI(self):         

#         self.statusbar = self.statusBar()
#         self.statusbar.showMessage('Ready')

#         menubar = self.menuBar()
#         menubar.setNativeMenuBar(False)
#         viewMenu = menubar.addMenu('View')

#         viewStatAct = QAction('View statusbar', self, checkable=True)
#         # 用checkable选项创建一个能选中的菜单
#         viewStatAct.setStatusTip('View statusbar')
#         viewStatAct.setChecked(True)
#         # 默认设置为选中状态
#         viewStatAct.triggered.connect(self.toggleMenu)

#         viewMenu.addAction(viewStatAct)

#         ################################
#         # exitAct = QAction('Exit', self, checkable=True)        
#         # exitAct.setShortcut('Ctrl+Q')
#         # exitAct.setStatusTip('Exit application')
#         # exitAct.setChecked(True)
#         # exitAct.triggered.connect(qApp.quit)

#         # viewMenu.addAction(exitAct)
#         ########################

#         self.setGeometry(300, 300, 300, 200)
#         self.setWindowTitle('Check menu')    
#         self.show()

#     def toggleMenu(self, state):

#         if state:
#             self.statusbar.show()
#         else:
#             self.statusbar.hide()


# if __name__ == '__main__':

#     app = QApplication(sys.argv)
#     ex = Example()
#     sys.exit(app.exec_())




# 右键菜单
# import sys
# from PyQt5.QtWidgets import QMainWindow, qApp, QMenu, QApplication

# class Example(QMainWindow):

#     def __init__(self):
#         super().__init__()

#         self.initUI()

#     def initUI(self):         

#         self.setGeometry(300, 300, 300, 200)
#         self.setWindowTitle('Context menu')    
#         self.show()

#     def contextMenuEvent(self, event):

#            cmenu = QMenu(self)

#            newAct = cmenu.addAction("New")
#            opnAct = cmenu.addAction("Open")
#            quitAct = cmenu.addAction("Quit")
#            action = cmenu.exec_(self.mapToGlobal(event.pos()))
#         #    使用exec_()方法显示菜单。从鼠标右键事件对象中获得当前坐标。
#         # mapToGlobal()方法把当前组件的相对坐标转换为窗口(window)的绝对坐标。

#            if action == quitAct:
#                qApp.quit()
#             #    如果右键菜单里触发了事件,也就触发了退出事件,执行关闭菜单行为

# if __name__ == '__main__':
#     app = QApplication(sys.argv)
#     ex = Example()
#     sys.exit(app.exec_())




# 工具栏
# import sys
# from PyQt5.QtWidgets import QMainWindow, QAction, qApp, QApplication
# from PyQt5.QtGui import QIcon

# class Example(QMainWindow):

#     def __init__(self):
#         super().__init__()

#         self.initUI()


#     def initUI(self):               

#         # exitAct = QAction(QIcon('exit24.png'), 'Exit', self)
#         exitAct = QAction('Exit11111', self)
#         exitAct.setShortcut('Ctrl+Q')
#         exitAct.triggered.connect(qApp.quit)

#         self.toolbar = self.addToolBar('Exit')
#         self.toolbar.addAction(exitAct)

#         self.setGeometry(300, 300, 300, 200)
#         self.setWindowTitle('Toolbar')    
#         self.show()

# if __name__ == '__main__':

#     app = QApplication(sys.argv)
#     ex = Example()
#     sys.exit(app.exec_())




# 主窗口
# 主窗口就是上面三种栏目的总称,现在我们把上面的三种栏在一个应用里展示出来。
# import sys
# from PyQt5.QtWidgets import QMainWindow, QTextEdit, QAction, QApplication
# from PyQt5.QtGui import QIcon

# class Example(QMainWindow):

#     def __init__(self):
#         super().__init__()

#         self.initUI()

#     def initUI(self):               

#         textEdit = QTextEdit()
#         self.setCentralWidget(textEdit)
#         # 这里创建了一个文本编辑区域,并把它放
#         # 在QMainWindow的中间区域。这个组件会占满所有剩余的区域

#         # exitAct = QAction(QIcon('exit24.png'), 'Exit', self)
#         exitAct = QAction('Exit111', self)
#         exitAct.setShortcut('Ctrl+Q')
#         exitAct.setStatusTip('Exit application')
#         exitAct.triggered.connect(self.close)
# #状态栏
#         self.statusBar()
# #菜单栏
#         menubar = self.menuBar()
#         menubar.setNativeMenuBar(False)
#         fileMenu = menubar.addMenu('&File')
#         fileMenu.addAction(exitAct)
# #工具栏
#         toolbar = self.addToolBar('Exit')
#         toolbar.addAction(exitAct)

#         self.setGeometry(300, 300, 350, 250)
#         self.setWindowTitle('Main window')    
#         self.show()

# if __name__ == '__main__':
#     app = QApplication(sys.argv)
#     ex = Example()
#     sys.exit(app.exec_())



#第三章

# 布局管理
'''
在一个GUI程序里,布局是一个很重要的方面。布
局就是如何管理应用中的元素和窗口。有两种方式可以搞定:绝对定位和PyQt5的layout类
'''
# 绝对定位
'''
每个程序都是以像素为单位区分元素的位置,衡量元素的大小。所以我
们完全可以使用绝对定位搞定每个元素和窗口的位置。但是这也有局限性:
1元素不会随着我们更改窗口的位置和大小而变化。
2不能适用于不同的平台和不同分辨率的显示器
3更改应用字体大小会破坏布局
4如果我们决定重构这个应用,需要全部计算一下每个元素的位置和大小
'''
# import sys
# from PyQt5.QtWidgets import QWidget, QLabel, QApplication

# class Example(QWidget):

#     def __init__(self):
#         super().__init__()

#         self.initUI()

#     def initUI(self):

#         lbl1 = QLabel('Zetcode', self)
#         lbl1.move(15, 10)

#         lbl2 = QLabel('tutorials', self)
#         lbl2.move(35, 40)

#         lbl3 = QLabel('for programmers', self)
#         lbl3.move(55, 70)        

#         self.setGeometry(300, 300, 250, 150)
#         self.setWindowTitle('Absolute')    
#         self.show()

# if __name__ == '__main__':
#     app = QApplication(sys.argv)
#     ex = Example()
#     sys.exit(app.exec_())

# 盒布局
'''
使用盒布局能让程序具有更强的适应性。这个才是布局一个应用的
更合适的方式。QHBoxLayout和QVBoxLayout是基本的布局类,分别是水平布局和垂直布局。
如果我们需要把两个按钮放在程序的右下角,创建这样的布局,我们只需要一个水平布局加一
个垂直布局的盒子就可以了。再用弹性布局增加一点间隙。
'''
# import sys
# from PyQt5.QtWidgets import (QWidget, QPushButton, 
#     QHBoxLayout, QVBoxLayout, QApplication)

# class Example(QWidget):

#     def __init__(self):
#         super().__init__()

#         self.initUI()

#     def initUI(self):

#         okButton = QPushButton("OK")
#         cancelButton = QPushButton("Cancel")
        
#         hbox = QHBoxLayout()#水平
#         hbox.addStretch(1)
#         hbox.addWidget(okButton)
#         hbox.addWidget(cancelButton)
#         # 创建一个水平布局,并增加弹性空间和两个按钮。
#         # stretch函数在两个按钮前面增加了一块弹性空间,它会将按钮挤到窗口的右边

#         vbox = QVBoxLayout()
#         vbox.addStretch(1)
#         vbox.addLayout(hbox)
#         #为了布局需要,我们把这个水平布局放
#         # 到了一个垂直布局盒里面。弹性元素会把水平布局挤到窗口的下边

#         self.setLayout(vbox)    

#         self.setGeometry(300, 300, 300, 150)
#         self.setWindowTitle('Buttons')    
#         self.show()

# '''
# 上面的例子完成了在应用的右下角放了两个按钮的需求。当改变窗口大小的
# 时候,它们能依然保持在相对的位置。我们同时使用了QHBoxLayout和QVBoxLayout
# '''
# if __name__ == '__main__':

#     app = QApplication(sys.argv)
#     ex = Example()
#     sys.exit(app.exec_())



# 栅格布局
'''
最常用的还是栅格布局了。这
种布局是把窗口分为行和列。创建和使用栅格布局,需要使用QGridLayout模块
'''
# import sys
# from PyQt5.QtWidgets import (QWidget, QGridLayout, 
#     QPushButton, QApplication)


# class Example(QWidget):

#     def __init__(self):
#         super().__init__()

#         self.initUI()


#     def initUI(self):

#         grid = QGridLayout()
#         self.setLayout(grid)

#         names = ['Cls', 'Bck', '', 'Close',
#                  '7', '8', '9', '/',
#                 '4', '5', '6', '*',
#                  '1', '2', '3', '-',
#                 '0', '.', '=', '+']

#         # print(names)

#         positions = [(i,j) for i in range(5) for j in range(4)]

#         # print(positions)
#         # print()
#         # print()
#         # print()
#         # print(*zip(positions,names))
#         # print(type(zip(positions,names)))
        
#         for position, name in zip(positions, names):
#             # print(position)
#             # print(*position)
#             # print(name)

#             if name == '':
#                 continue
#             button = QPushButton(name)
#             grid.addWidget(button, *position)

#         self.move(300, 150)
#         self.setWindowTitle('Calculator')
#         self.show()


# if __name__ == '__main__':

#     app = QApplication(sys.argv)
#     ex = Example()
#     sys.exit(app.exec_())





# 制作提交反馈信息的布局

# import sys
# from PyQt5.QtWidgets import (QWidget, QLabel, QLineEdit, 
#     QTextEdit, QGridLayout, QApplication)

# class Example(QWidget):

#     def __init__(self):
#         super().__init__()

#         self.initUI()


#     def initUI(self):

#         title = QLabel('Title')
#         author = QLabel('Author')
#         review = QLabel('Review')

#         titleEdit = QLineEdit()
#         authorEdit = QLineEdit()
#         reviewEdit = QTextEdit()

#         grid = QGridLayout()
#         grid.setSpacing(10)#创建标签之间的空间

#         grid.addWidget(title, 1, 0)
#         grid.addWidget(titleEdit, 1, 1)

#         grid.addWidget(author, 2, 0)
#         grid.addWidget(authorEdit, 2, 1)

#         grid.addWidget(review, 3, 0)
#         grid.addWidget(reviewEdit, 3, 1, 5, 1)
# # 我们可以指定组件的跨行和跨列的大小。这里我们指定这个元素跨5行显示


#         self.setLayout(grid) 

#         self.setGeometry(300, 300, 350, 300)
#         self.setWindowTitle('Review')    
#         self.show()


# if __name__ == '__main__':

#     app = QApplication(sys.argv)
#     ex = Example()
#     sys.exit(app.exec_())

事件和信号&对话&控件

# 第四章

# 事件和信号
'''
所有的应用都是事件驱动的。事件大部分都是由用户的行为产生的,
当然也有其他的事件产生方式,比如网络的连接,窗口管理器或者定时器等。
调用应用的exec_()方法时,应用会进入主循环,主循环会监听和分发事件。
'''
# Signals & slots

# import sys
# from PyQt5.QtCore import Qt
# from PyQt5.QtWidgets import (QWidget, QLCDNumber, QSlider, 
#     QVBoxLayout, QApplication)


# class Example(QWidget):

#     def __init__(self):
#         super().__init__()

#         self.initUI()


#     def initUI(self):

#         lcd = QLCDNumber(self)
#         sld = QSlider(Qt.Horizontal, self)

#         vbox = QVBoxLayout()#垂直布局
#         vbox.addWidget(lcd)
#         vbox.addWidget(sld)

#         self.setLayout(vbox)
#         sld.valueChanged.connect(lcd.display)

#         self.setGeometry(300, 300, 250, 150)
#         self.setWindowTitle('Signal and slot')
#         self.show()

# 上面的例子中,显示了QtGui.QLCDNumb
# er和QtGui.QSlider模块,我们能拖动滑块让数字跟着发生改变

# if __name__ == '__main__':

#     app = QApplication(sys.argv)
#     ex = Example()
#     sys.exit(app.exec_())





# 重构事件处理器
# import sys
# from PyQt5.QtCore import Qt
# from PyQt5.QtWidgets import QWidget, QApplication

# class Example(QWidget):

#     def __init__(self):
#         super().__init__()

#         self.initUI()


#     def initUI(self):      

#         self.setGeometry(300, 300, 250, 150)
#         self.setWindowTitle('Event handler')
#         self.show()


#     def keyPressEvent(self, e):

#         if e.key() == Qt.Key_Escape:
#             self.close()
# # 这个例子中,我们替换了事件处理器函数keyPressEvent()
# # 此时如果按下ESC键程序就会退出

# if __name__ == '__main__':

#     app = QApplication(sys.argv)
#     ex = Example()
#     sys.exit(app.exec_())




# 事件对象
# import sys
# from PyQt5.QtCore import Qt
# from PyQt5.QtWidgets import QWidget, QApplication, QGridLayout, QLabel

# class Example(QWidget):

#     def __init__(self):
#         super().__init__()

#         self.initUI()

#     def initUI(self):      

#         grid = QGridLayout()
#         grid.setSpacing(10)

#         x = 0
#         y = 0

#         self.text = "x: {0},  y: {1}".format(x, y)

#         self.label = QLabel(self.text, self)
#         grid.addWidget(self.label, 0, 0, Qt.AlignTop)

#         self.setMouseTracking(True)

#         self.setLayout(grid)#事件追踪默认没有开启,当开启后才会追踪鼠标的点击事件

#         self.setGeometry(300, 300, 350, 200)
#         self.setWindowTitle('Event object')
#         self.show()

#     def mouseMoveEvent(self, e):
#         '''
#         e代表了事件对象。里面有我们触发事件(鼠标移
#         动)的事件对象。x()和y()方法得到鼠标的x和y坐
#         标点,然后拼成字符串输出到QLabel组件里
#         '''
#         x = e.x()
#         y = e.y()

#         text = "x: {0},  y: {1}".format(x, y)
#         self.label.setText(text)

# if __name__ == '__main__':

#     app = QApplication(sys.argv)
#     ex = Example()
#     sys.exit(app.exec_())




# 事件发送
# import sys
# from PyQt5.QtWidgets import QMainWindow, QPushButton, QApplication

# class Example(QMainWindow):

#     def __init__(self):
#         super().__init__()

#         self.initUI()

#     def initUI(self):      

#         btn1 = QPushButton("Button 1", self)
#         btn1.move(30, 50)

#         btn2 = QPushButton("Button 2", self)
#         btn2.move(150, 50)

#         btn1.clicked.connect(self.buttonClicked)            
#         btn2.clicked.connect(self.buttonClicked)

#         self.statusBar()

#         self.setGeometry(300, 300, 290, 150)
#         self.setWindowTitle('Event sender')
#         self.show()


#     def buttonClicked(self):
# # 我们用调用sender()方法的方式决定了事件源。状态栏显示了被点击的按钮。
# # 程序展示
#         sender = self.sender()
#         self.statusBar().showMessage(sender.text() + ' was pressed')


# if __name__ == '__main__':

#     app = QApplication(sys.argv)
#     ex = Example()
#     sys.exit(app.exec_())





# 信号发送
'''
我们创建了一个叫closeApp的
信号,这个信号会在鼠标按下的时候触发,事件与QMainWindow绑定。
'''
# import sys
# from PyQt5.QtCore import pyqtSignal, QObject
# from PyQt5.QtWidgets import QMainWindow, QApplication

# class Communicate(QObject):

#     closeApp = pyqtSignal() 
# # Communicate类创建了一个pyqtSignal()属性的信号

# class Example(QMainWindow):

#     def __init__(self):
#         super().__init__()

#         self.initUI()


#     def initUI(self):      

#         self.c = Communicate()
#         self.c.closeApp.connect(self.close)       

#         self.setGeometry(300, 300, 290, 150)
#         self.setWindowTitle('Emit signal')
#         self.show()


#     def mousePressEvent(self, event):

#         self.c.closeApp.emit()
# # 点击窗口的时候,发送closeApp信号,程序终止

# if __name__ == '__main__':

#     app = QApplication(sys.argv)
#     ex = Example()
#     sys.exit(app.exec_())




#第五章

# 对话框
'''
对话框是一个现代GUI应用不可或缺的一部分。对
话是两个人之间的交流,对话框就是人与电脑之间的对话。
对话框用来输入数据,修改数据,修改应用设置等等。

'''
# 输入文字

# from PyQt5.QtWidgets import (QWidget, QPushButton, QLineEdit, 
#     QInputDialog, QApplication)
# import sys

# class Example(QWidget):

#     def __init__(self):
#         super().__init__()

#         self.initUI()


#     def initUI(self):

#         self.btn = QPushButton('Dialog', self)
#         self.btn.move(20, 20)
#         self.btn.clicked.connect(self.showDialog)

#         self.le = QLineEdit(self)
#         self.le.move(130, 22)

#         self.setGeometry(300, 300, 290, 150)
#         self.setWindowTitle('Input dialog')
#         self.show()


#     def showDialog(self):

#         text, ok = QInputDialog.getText(self, 'Input Dialog', 
#             'Enter your name:')
# # 这是显示一个输入框的代码。第一个参数是输入框的标题,第二个参数是输入框
# # 的占位符。对话框返回输入内容和一个布尔值,如果点击的是OK按钮,布尔值就返回True。
#         if ok:
#             self.le.setText(str(text))


# if __name__ == '__main__':

#     app = QApplication(sys.argv)
#     ex = Example()
#     sys.exit(app.exec_())




# 选取颜色
# from PyQt5.QtWidgets import (QWidget, QPushButton, QFrame, 
#     QColorDialog, QApplication)
# from PyQt5.QtGui import QColor
# import sys
# '''
# 例子里有一个按钮和一个QFrame,
# 默认的背景颜色为黑色,我们可以使用QColorDialog改变背景颜色。
# '''
# class Example(QWidget):

#     def __init__(self):
#         super().__init__()

#         self.initUI()


#     def initUI(self):      

#         col = QColor(0, 0, 0) #初始化QtGui.QFrame的背景颜色

#         self.btn = QPushButton('Dialog', self)
#         self.btn.move(20, 20)

#         self.btn.clicked.connect(self.showDialog)

#         self.frm = QFrame(self)
#         self.frm.setStyleSheet("QWidget { background-color: %s }" 
#             % col.name())
#         #设置颜色
#         self.frm.setGeometry(130, 22, 100, 100)            

#         self.setGeometry(300, 300, 250, 180)
#         self.setWindowTitle('Color dialog')
#         self.show()


#     def showDialog(self):

#         col = QColorDialog.getColor()#QColorDialog改变背景颜色

#         if col.isValid():
#             self.frm.setStyleSheet("QWidget { background-color: %s }"
#                 % col.name())


# if __name__ == '__main__':

#     app = QApplication(sys.argv)
#     ex = Example()
#     sys.exit(app.exec_())





# 选择字体
# from PyQt5.QtWidgets import (QWidget, QVBoxLayout, QPushButton, 
#     QSizePolicy, QLabel, QFontDialog, QApplication)
# import sys

# class Example(QWidget):

#     def __init__(self):
#         super().__init__()

#         self.initUI()


#     def initUI(self):      

#         vbox = QVBoxLayout()

#         btn = QPushButton('Dialog', self)
#         btn.setSizePolicy(QSizePolicy.Fixed,
#             QSizePolicy.Fixed)
#         btn.move(20, 20)
#         btn.clicked.connect(self.showDialog)
#         vbox.addWidget(btn)

#         self.lbl = QLabel('Knowledge only matters', self)
#         self.lbl.move(130, 20)

#         vbox.addWidget(self.lbl)
#         self.setLayout(vbox)          

#         self.setGeometry(300, 300, 250, 180)
#         self.setWindowTitle('Font dialog')
#         self.show()


#     def showDialog(self):

#         font, ok = QFontDialog.getFont()
#         # getFont()方法返回一个字体名称和状态信息。状态信息有OK和其他两种。
#         if ok:
#             self.lbl.setFont(font)


# if __name__ == '__main__':

#     app = QApplication(sys.argv)
#     ex = Example()
#     sys.exit(app.exec_())





# 选择文件
# QFileDialog给用户提供文件或者文件夹选择的功能。能打开和保存文件
# from PyQt5.QtWidgets import (QMainWindow, QTextEdit, 
#     QAction, QFileDialog, QApplication)
# from PyQt5.QtGui import QIcon
# import sys

# class Example(QMainWindow):

#     def __init__(self):
#         super().__init__()

#         self.initUI()


#     def initUI(self):      

#         self.textEdit = QTextEdit()
#         self.setCentralWidget(self.textEdit)
#         self.statusBar()

#         # openFile = QAction(QIcon('open.png'), 'Open', self)
#         openFile = QAction('Open', self)
#         openFile.setShortcut('Ctrl+O')
#         openFile.setStatusTip('Open new File')
#         openFile.triggered.connect(self.showDialog)

#         menubar = self.menuBar()
#         menubar.setNativeMenuBar(False)
#         fileMenu = menubar.addMenu('&File')
#         fileMenu.addAction(openFile)       

#         self.setGeometry(300, 300, 350, 300)
#         self.setWindowTitle('File dialog')
#         self.show()


#     def showDialog(self):

#         fname = QFileDialog.getOpenFileName(self, 'Open file', '/home')
# # getOpenFileName()方法的第一个参数是说
# # 明文字,第二个参数是默认打开的文件夹路径。默认情况下显示所有类型的文件。
#         if fname[0]:
#             f = open(fname[0], 'r')

#             with f:
#                 data = f.read()
#                 self.textEdit.setText(data)        

# if __name__ == '__main__':

#     app = QApplication(sys.argv)
#     ex = Example()
#     sys.exit(app.exec_())




# 第六章
# 控件(1)

# QCheckBox
# from PyQt5.QtWidgets import QWidget, QCheckBox, QApplication
# from PyQt5.QtCore import Qt
# import sys

# class Example(QWidget):

#     def __init__(self):
#         super().__init__()

#         self.initUI()


#     def initUI(self):      

#         cb = QCheckBox('Show title', self)
#         cb.move(20, 20)
#         cb.toggle()
#         #要设置窗口标题,我们就要
#         # 检查单选框的状态。默认情况下,窗口没有标题,单选框未选中。
        
#         cb.stateChanged.connect(self.changeTitle)

#         self.setGeometry(300, 300, 250, 150)
#         self.setWindowTitle('QCheckBox')
#         self.show()


#     def changeTitle(self, state):

#         if state == Qt.Checked:
#             self.setWindowTitle('QCheckBox')
#         else:
#             self.setWindowTitle(' ')


# if __name__ == '__main__':

#     app = QApplication(sys.argv)
#     ex = Example()
#     sys.exit(app.exec_())




# 切换按钮
'''
切换按钮就是QPushButton的一种特殊模式。 它只有两种
状态:按下和未按下。我们在点击的时候切换两种状态,有很多场景会使用到这个功能
'''
# from PyQt5.QtWidgets import (QWidget, QPushButton, 
#     QFrame, QApplication)
# from PyQt5.QtGui import QColor
# import sys

# class Example(QWidget):

#     def __init__(self):
#         super().__init__()

#         self.initUI()


#     def initUI(self):      

#         self.col = QColor(0, 0, 0)       

#         redb = QPushButton('Red', self)
#         redb.setCheckable(True)
#         redb.move(10, 10)
#         redb.clicked[bool].connect(self.setColor)

#         greenb = QPushButton('Green', self)
#         greenb.setCheckable(True)
#         greenb.move(10, 60)
#         greenb.clicked[bool].connect(self.setColor)

#         blueb = QPushButton('Blue', self)
#         blueb.setCheckable(True)
#         blueb.move(10, 110)
#         blueb.clicked[bool].connect(self.setColor)

#         self.square = QFrame(self)
#         self.square.setGeometry(150, 20, 100, 100)
#         self.square.setStyleSheet("QWidget { background-color: %s }" %  
#             self.col.name())

#         self.setGeometry(300, 300, 280, 170)
#         self.setWindowTitle('Toggle button')
#         self.show()


#     def setColor(self, pressed):

#         source = self.sender()#获取被点击的按钮

#         if pressed:
#             val = 255
#         else: val = 0

#         if source.text() == "Red":
#             self.col.setRed(val)                
#         elif source.text() == "Green":
#             self.col.setGreen(val)             
#         else:
#             self.col.setBlue(val) 

#         self.square.setStyleSheet("QFrame { background-color: %s }" %
#             self.col.name())  


# if __name__ == '__main__':

#     app = QApplication(sys.argv)
#     ex = Example()
#     sys.exit(app.exec_())




# 滑块
# from PyQt5.QtWidgets import (QWidget, QSlider, 
#     QLabel, QApplication)
# from PyQt5.QtCore import Qt
# from PyQt5.QtGui import QPixmap
# import sys

# class Example(QWidget):

#     def __init__(self):
#         super().__init__()

#         self.initUI()


#     def initUI(self):      

#         sld = QSlider(Qt.Horizontal, self)
#         # 创建一个水平的QSlider
#         sld.setFocusPolicy(Qt.NoFocus)
#         sld.setGeometry(30, 40, 100, 30)
#         sld.valueChanged[int].connect(self.changeValue)

#         self.label = QLabel(self)
#         self.label.setPixmap(QPixmap('Desktop/1.png'))

#         self.label.setGeometry(160, 40, 80, 30)

#         self.setGeometry(300, 300, 280, 170)
#         self.setWindowTitle('QSlider')
#         self.show()


#     def changeValue(self, value):

#         if value == 0:
#             self.label.setPixmap(QPixmap('mute.png'))
#         elif value > 0 and value <= 30:
#             self.label.setPixmap(QPixmap('min.png'))
#         elif value > 30 and value < 80:
#             self.label.setPixmap(QPixmap('med.png'))
#         else:
#             self.label.setPixmap(QPixmap('Desktop/2.png'))

# if __name__ == '__main__':
#     app = QApplication(sys.argv)
#     ex = Example()
#     sys.exit(app.exec_())

# 进度条
# from PyQt5.QtWidgets import (QWidget, QProgressBar, 
#     QPushButton, QApplication)
# from PyQt5.QtCore import QBasicTimer
# import sys

# class Example(QWidget):

#     def __init__(self):
#         super().__init__()

#         self.initUI()


#     def initUI(self):      

#         self.pbar = QProgressBar(self)
#         self.pbar.setGeometry(30, 40, 200, 25)

#         self.btn = QPushButton('Start', self)
#         self.btn.move(40, 80)
#         self.btn.clicked.connect(self.doAction)

#         self.timer = QBasicTimer()
#         self.step = 0

#         self.setGeometry(300, 300, 280, 170)
#         self.setWindowTitle('QProgressBar')
#         self.show()


#     def timerEvent(self, e):

#         if self.step >= 100:
#             self.timer.stop()
#             self.btn.setText('Finished')
#             return

#         self.step = self.step + 1
#         self.pbar.setValue(self.step)

# # doAction()方法是用来控制开始和停止的
#     def doAction(self):

#         if self.timer.isActive():
#             self.timer.stop()
#             self.btn.setText('Start')
#         else:
#             self.timer.start(100, self)
#             self.btn.setText('Stop')


# if __name__ == '__main__':

#     app = QApplication(sys.argv)
#     ex = Example()
#     sys.exit(app.exec_())




# 日历
# from PyQt5.QtWidgets import (QWidget, QCalendarWidget, 
#     QLabel, QApplication, QVBoxLayout)
# from PyQt5.QtCore import QDate
# import sys

# class Example(QWidget):

#     def __init__(self):
#         super().__init__()

#         self.initUI()


#     def initUI(self):      

#         vbox = QVBoxLayout(self)

#         cal = QCalendarWidget(self)
#         cal.setGridVisible(True)
#         cal.clicked[QDate].connect(self.showDate)
#         # 选择一个日期时,QDate的点击信号就触发了,
#         # 把这个信号和我们自己定义的showDate()方法关联起来

#         vbox.addWidget(cal)

#         self.lbl = QLabel(self)
#         date = cal.selectedDate()
#         self.lbl.setText(date.toString())
#         # 使用selectedDate()方法获取选中的日期,
#         # 然后把日期对象转成字符串,在标签里面显示出来

#         vbox.addWidget(self.lbl)

#         self.setLayout(vbox)

#         self.setGeometry(300, 300, 350, 300)
#         self.setWindowTitle('Calendar')
#         self.show()


#     def showDate(self, date):     

#         self.lbl.setText(date.toString())


# if __name__ == '__main__':

#     app = QApplication(sys.argv)
#     ex = Example()
#     sys.exit(app.exec_())






# 控件(2)

# 图片
# from PyQt5.QtWidgets import (QWidget, QHBoxLayout, 
#     QLabel, QApplication)
# from PyQt5.QtGui import QPixmap
# import sys

# class Example(QWidget):

#     def __init__(self):
#         super().__init__()

#         self.initUI()


#     def initUI(self):      

#         hbox = QHBoxLayout(self)
#         pixmap = QPixmap('Desktop/1.png')

#         lbl = QLabel(self)
#         lbl.setPixmap(pixmap)

#         hbox.addWidget(lbl)
#         self.setLayout(hbox)

#         self.move(300, 200)
#         self.setWindowTitle('pyqt5')
#         self.show()        


# if __name__ == '__main__':

#     app = QApplication(sys.argv)
#     ex = Example()
#     sys.exit(app.exec_())



# 行编辑
'''
例子中展示了一个编辑组件和一个标签,我们在输入框里键入的文本,会立即在标签里显示出来
'''
# import sys
# from PyQt5.QtWidgets import (QWidget, QLabel, 
#     QLineEdit, QApplication)


# class Example(QWidget):

#     def __init__(self):
#         super().__init__()

#         self.initUI()


#     def initUI(self):      

#         self.lbl = QLabel(self)
#         qle = QLineEdit(self)

#         qle.move(60, 100)
#         self.lbl.move(60, 40)

#         qle.textChanged[str].connect(self.onChanged)

#         self.setGeometry(300, 300, 280, 170)
#         self.setWindowTitle('QLineEdit')
#         self.show()


#     def onChanged(self, text):
#         # 在onChanged()方法内部,我们把文本框里的值赋值给了标
#         # 签组件,然后调用adjustSize()方法让标签自适应文本内容。
#         self.lbl.setText(text)
#         self.lbl.adjustSize()        

# if __name__ == '__main__':
#     app = QApplication(sys.argv)
#     ex = Example()
#     sys.exit(app.exec_())

# QSplitter
'''
QSplitter组件能让用户通过拖拽分割线的方式改
变子窗口大小的组件。本例中我们展示用两个分割线隔开的三个QFrame组件
'''
# from PyQt5.QtWidgets import (QWidget, QHBoxLayout, QFrame, 
#     QSplitter, QStyleFactory, QApplication)
# from PyQt5.QtCore import Qt
# import sys

# class Example(QWidget):

#     def __init__(self):
#         super().__init__()

#         self.initUI()

#     def initUI(self):      

#         hbox = QHBoxLayout(self)

#         topleft = QFrame(self)
#         topleft.setFrameShape(QFrame.StyledPanel)
#         # 为了更清楚的看到分割线,我们使用了设置好的子窗口样式。

#         topright = QFrame(self)
#         topright.setFrameShape(QFrame.StyledPanel)

#         bottom = QFrame(self)
#         bottom.setFrameShape(QFrame.StyledPanel)


#         splitter1 = QSplitter(Qt.Horizontal)
#         splitter1.addWidget(topleft)
#         splitter1.addWidget(topright)
#         # 创建一个QSplitter组件,并在里面添加了两个框架

#         splitter2 = QSplitter(Qt.Vertical)
#         splitter2.addWidget(splitter1)
#         splitter2.addWidget(bottom)
#         # 也可以在分割线里面再进行分割

#         hbox.addWidget(splitter2)
#         self.setLayout(hbox)

#         self.setGeometry(300, 300, 300, 200)
#         self.setWindowTitle('QSplitter')
#         self.show()
  
# if __name__ == '__main__':

#     app = QApplication(sys.argv)
#     ex = Example()
#     sys.exit(app.exec_())





# 下拉选框

# QComboBox组件能让用户在多个选择项中选择一个
from PyQt5.QtWidgets import (QWidget, QLabel, 
    QComboBox, QApplication)
import sys

class Example(QWidget):

    def __init__(self):
        super().__init__()

        self.initUI()


    def initUI(self):      

        self.lbl = QLabel("Ubuntu", self)

        combo = QComboBox(self)
        combo.addItem("Ubuntu")
        combo.addItem("Mandriva")
        combo.addItem("Fedora")
        combo.addItem("Arch")
        combo.addItem("Gentoo")

        combo.move(50, 50)
        self.lbl.move(50, 150)

        combo.activated[str].connect(self.onActivated)        

        self.setGeometry(300, 300, 300, 200)
        self.setWindowTitle('QComboBox')
        self.show()


    def onActivated(self, text):

        self.lbl.setText(text)
        self.lbl.adjustSize()  
        # 在方法内部,设置标签内容为选定的字符串,然后设置自适应文本大小

if __name__ == '__main__':

    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())

拖拽&绘图&自定义

#第八章
# 拖拽
'''
在GUI里,拖放是指用户点击一个虚拟的对象,拖动,然后放置到另外一个对象上面的动作。
一般情况下,需要调用很多动作和方法,创建很多变量。
拖放能让用户很直观的操作很复杂的逻辑。
一般情况下,我们可以拖放两种东西:数据和图形界面。把一个图像从一个应用拖放到另外一个应用
上的实质是操作二进制数据。把一个表格从Firefox上拖放到另外一个位置 的实质是操作一个图形组
'''

# 简单的拖放
# 本例使用了QLineEdit和QPushButton。把一个文本从编辑框里拖到
# 按钮上,更新按钮上的标签(文字)
# from PyQt5.QtWidgets import (QPushButton, QWidget, 
#     QLineEdit, QApplication)
# import sys

# class Button(QPushButton):

#     def __init__(self, title, parent):
#         super().__init__(title, parent)

#         self.setAcceptDrops(True)#激活组件的拖拽事件


#     def dragEnterEvent(self, e):
#         # 首先,我们重构了dragEnterEvent()方法
#         # 。设定好接受拖拽的数据类型(plain text)。

#         if e.mimeData().hasFormat('text/plain'):
#             e.accept()
#         else:
#             e.ignore() 

#     def dropEvent(self, e):
# # 重构dropEvent()方法,更改按钮接受鼠标的释放事件的默认行为
#         self.setText(e.mimeData().text()) 


# class Example(QWidget):

#     def __init__(self):
#         super().__init__()

#         self.initUI()

#     def initUI(self):
# # QLineEdit默认支持拖拽操作,所以我们只要调用setDragEnabled()方法使用就行了。
#         edit = QLineEdit('', self)
#         edit.setDragEnabled(True)
#         edit.move(30, 65)

#         button = Button("Button", self)
#         button.move(190, 65)

#         self.setWindowTitle('Simple drag and drop')
#         self.setGeometry(300, 300, 300, 150)

#         self.show()

# if __name__ == '__main__':
#     app = QApplication(sys.argv)
#     ex = Example()
#     app.exec_()





# 拖放按钮组件
# from PyQt5.QtWidgets import QPushButton, QWidget, QApplication
# from PyQt5.QtCore import Qt, QMimeData
# from PyQt5.QtGui import QDrag
# import sys

# class Button(QPushButton):

#     def __init__(self, title, parent):
#         super().__init__(title, parent)


#     def mouseMoveEvent(self, e):
# # 我们只劫持按钮的右键事件,左键的操作还是默认行为
#         if e.buttons() != Qt.RightButton:
#             return

#         mimeData = QMimeData()

#         drag = QDrag(self)
#         # 创建一个QDrag对象,用来传输MIME-based数据
#         drag.setMimeData(mimeData)
#         drag.setHotSpot(e.pos() - self.rect().topLeft())

#         dropAction = drag.exec_(Qt.MoveAction)


#     def mousePressEvent(self, e):

#         super().mousePressEvent(e)

#         if e.button() == Qt.LeftButton:
#             print('press')


# class Example(QWidget):

#     def __init__(self):
#         super().__init__()

#         self.initUI()


#     def initUI(self):

#         self.setAcceptDrops(True)

#         self.button = Button('Button', self)
#         self.button.move(100, 65)

#         self.setWindowTitle('Click or Move')
#         self.setGeometry(300, 300, 280, 150)
#         self.show()


#     def dragEnterEvent(self, e):

#         e.accept()


#     def dropEvent(self, e):

#         position = e.pos()
#         self.button.move(position)

#         e.setDropAction(Qt.MoveAction)
#         e.accept()


# if __name__ == '__main__':
#     app = QApplication(sys.argv)
#     ex = Example()
#     app.exec_()


# 上面的例子中,窗口上有一个
# PushButton组件。左键点击按钮,控制台就会输出press。右键可以点击然后拖动按钮。    





# 绘图
# 文本涂鸦

# import sys
# from PyQt5.QtWidgets import QWidget, QApplication
# from PyQt5.QtGui import QPainter, QColor, QFont
# from PyQt5.QtCore import Qt

# class Example(QWidget):

#     def __init__(self):
#         super().__init__()

#         self.initUI()


#     def initUI(self):      

#         self.text = "xzbvb xzv bc    zzv"

#         self.setGeometry(300, 300, 280, 170)
#         self.setWindowTitle('Drawing text')
#         self.show()


#     def paintEvent(self, event):

#         qp = QPainter()
#         qp.begin(self)
#         self.drawText(event, qp)
#         qp.end()


#     def drawText(self, event, qp):

#         qp.setPen(QColor(168, 34, 3))
#         qp.setFont(QFont('Decorative', 10))
#         # 为文字绘画定义了笔和字体
#         qp.drawText(event.rect(), Qt.AlignCenter, self.text)        
#         # 在窗口里绘制文本,rect()方法返回要更新的矩形区域。


# if __name__ == '__main__':

#     app = QApplication(sys.argv)
#     ex = Example()
#     sys.exit(app.exec_())




# 点的绘画

# from PyQt5.QtWidgets import QWidget, QApplication
# from PyQt5.QtGui import QPainter
# from PyQt5.QtCore import Qt
# import sys, random

# class Example(QWidget):

#     def __init__(self):
#         super().__init__()

#         self.initUI()


#     def initUI(self):      

#         self.setGeometry(300, 300, 300, 190)
#         self.setWindowTitle('Points')
#         self.show()


#     def paintEvent(self, e):

#         qp = QPainter()
#         qp.begin(self)
#         self.drawPoints(qp)
#         qp.end()


#     def drawPoints(self, qp):

#         qp.setPen(Qt.red)
#         # 设置笔的颜色为红色,使用的是预定义好的颜色
#         size = self.size()
#         # 每次更改窗口大小,都会产生绘画事件,从size()
#         # 方法里获得当前窗口的大小,然后把产生的点随机的分配到窗口的所有位置上

#         for i in range(1000):
#             x = random.randint(1, size.width()-1)
#             y = random.randint(1, size.height()-1)
#             qp.drawPoint(x, y) #drawPoint()方法绘图    


# if __name__ == '__main__':

#     app = QApplication(sys.argv)
#     ex = Example()
#     sys.exit(app.exec_())




# 颜色
# from PyQt5.QtWidgets import QWidget, QApplication
# from PyQt5.QtGui import QPainter, QColor, QBrush
# import sys

# class Example(QWidget):

#     def __init__(self):
#         super().__init__()

#         self.initUI()


#     def initUI(self):      

#         self.setGeometry(300, 300, 350, 100)
#         self.setWindowTitle('Colours')
#         self.show()


#     def paintEvent(self, e):

#         qp = QPainter()
#         qp.begin(self)
#         self.drawRectangles(qp)
#         qp.end()


#     def drawRectangles(self, qp):

#         col = QColor(0, 0, 0)
#         col.setNamedColor('#d4d4d4')
#         # 使用16进制的方式定义一个颜色
#         qp.setPen(col)

#         qp.setBrush(QColor(200, 0, 0))
#         qp.drawRect(10, 15, 90, 60)
#         # 定义了一个笔刷,并画出了一个矩形。笔刷是用来画一个物体的背景。
#         # drawRect()有四个参数,分别是矩形的x、y、w、h。 然后用笔刷和矩形进行绘画。

#         qp.setBrush(QColor(255, 80, 0, 160))
#         qp.drawRect(130, 15, 90, 60)

#         qp.setBrush(QColor(25, 0, 90, 200))
#         qp.drawRect(250, 15, 90, 60)


# if __name__ == '__main__':

#     app = QApplication(sys.argv)
#     ex = Example()
#     sys.exit(app.exec_())




# QPen
'''
QPen是基本的绘画对象,能用来画直线、曲线、矩形框、椭圆、多边形和其他形状。
'''

# from PyQt5.QtWidgets import QWidget, QApplication
# from PyQt5.QtGui import QPainter, QPen
# from PyQt5.QtCore import Qt
# import sys

# class Example(QWidget):

#     def __init__(self):
#         super().__init__()

#         self.initUI()


#     def initUI(self):      

#         self.setGeometry(300, 300, 280, 270)
#         self.setWindowTitle('Pen styles')
#         self.show()


#     def paintEvent(self, e):

#         qp = QPainter()
#         qp.begin(self)
#         self.drawLines(qp)
#         qp.end()


#     def drawLines(self, qp):

#         pen = QPen(Qt.black, 2, Qt.SolidLine)
#         # 新建一个QPen对象,设置颜色黑色,宽2像素,这
#         # 样就能看出来各个笔样式的区别。Qt.SolidLine是预定义样式的一种。
#         qp.setPen(pen)
#         qp.drawLine(20, 40, 250, 40)

#         pen.setStyle(Qt.DashLine)
#         qp.setPen(pen)
#         qp.drawLine(20, 80, 250, 80)

#         pen.setStyle(Qt.DashDotLine)
#         qp.setPen(pen)
#         qp.drawLine(20, 120, 250, 120)

#         pen.setStyle(Qt.DotLine)
#         qp.setPen(pen)
#         qp.drawLine(20, 160, 250, 160)

#         pen.setStyle(Qt.DashDotDotLine)
#         qp.setPen(pen)
#         qp.drawLine(20, 200, 250, 200)

#         pen.setStyle(Qt.CustomDashLine)
#         pen.setDashPattern([1, 6, 5, 6])
#         qp.setPen(pen)
#         qp.drawLine(20, 240, 250, 240)
#         '''
#         这里我们自定义了一个笔的样式。定义为Qt.CustomDashLine然后调用
#         setDashPattern()方法。数字列表是线的样式,要求必须是个数为奇数,奇数位定义
#         的是空格,偶数位为线长,数字越大,空格或线长越大,比如本例的就是1素线,4
#         素空格,5像素线,4像素空格。
#         '''


# if __name__ == '__main__':

#     app = QApplication(sys.argv)
#     ex = Example()
#     sys.exit(app.exec_())






# QBrush

# from PyQt5.QtWidgets import QWidget, QApplication
# from PyQt5.QtGui import QPainter, QBrush
# from PyQt5.QtCore import Qt
# import sys

# class Example(QWidget):

#     def __init__(self):
#         super().__init__()

#         self.initUI()


#     def initUI(self):      

#         self.setGeometry(300, 300, 355, 280)
#         self.setWindowTitle('Brushes')
#         self.show()


#     def paintEvent(self, e):

#         qp = QPainter()
#         qp.begin(self)
#         self.drawBrushes(qp)
#         qp.end()


#     def drawBrushes(self, qp):

#         brush = QBrush(Qt.SolidPattern)
#         qp.setBrush(brush)
#         qp.drawRect(10, 15, 90, 60)

#         brush.setStyle(Qt.Dense1Pattern)
#         qp.setBrush(brush)
#         qp.drawRect(130, 15, 90, 60)

#         brush.setStyle(Qt.Dense2Pattern)
#         qp.setBrush(brush)
#         qp.drawRect(250, 15, 90, 60)

#         brush.setStyle(Qt.DiagCrossPattern)
#         qp.setBrush(brush)
#         qp.drawRect(10, 105, 90, 60)

#         brush.setStyle(Qt.Dense5Pattern)
#         qp.setBrush(brush)
#         qp.drawRect(130, 105, 90, 60)

#         brush.setStyle(Qt.Dense6Pattern)
#         qp.setBrush(brush)
#         qp.drawRect(250, 105, 90, 60)

#         brush.setStyle(Qt.HorPattern)
#         qp.setBrush(brush)
#         qp.drawRect(10, 195, 90, 60)

#         brush.setStyle(Qt.VerPattern)
#         qp.setBrush(brush)
#         qp.drawRect(130, 195, 90, 60)

#         brush.setStyle(Qt.BDiagPattern)
#         qp.setBrush(brush)
#         qp.drawRect(250, 195, 90, 60)
# # 创建了一个笔刷对象,添加笔刷样式,然后调用drawRect()方法画图。

# if __name__ == '__main__':

#     app = QApplication(sys.argv)
#     ex = Example()
#     sys.exit(app.exec_())






# 贝塞尔曲线

from PyQt5.QtWidgets import QWidget, QApplication
from PyQt5.QtGui import QPainter, QPainterPath
from PyQt5.QtCore import Qt
import sys

class Example(QWidget):

    def __init__(self):
        super().__init__()

        self.initUI()


    def initUI(self):      

        self.setGeometry(300, 300, 380, 250)
        self.setWindowTitle('Bézier curve')
        self.show()


    def paintEvent(self, e):

        qp = QPainter()
        qp.begin(self)
        qp.setRenderHint(QPainter.Antialiasing)
        self.drawBezierCurve(qp)
        qp.end()


    def drawBezierCurve(self, qp):

        path = QPainterPath()
        path.moveTo(30, 30)
        path.cubicTo(30, 30, 200, 350, 350, 30)

        qp.drawPath(path)

        # 用QPainterPath路径创建贝
        # 
        # 塞尔曲线。使用cubicTo()方法生成,分别需要三个点:起始点,控制点和终止点
        # drawPath()绘制最后的图像


if __name__ == '__main__':

    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())




# 自定义组件
# Burning widget

# from PyQt5.QtWidgets import (QWidget, QSlider, QApplication, 
#     QHBoxLayout, QVBoxLayout)
# from PyQt5.QtCore import QObject, Qt, pyqtSignal
# from PyQt5.QtGui import QPainter, QFont, QColor, QPen
# import sys

# class Communicate(QObject):

#     updateBW = pyqtSignal(int)


# class BurningWidget(QWidget):

#     def __init__(self):      
#         super().__init__()

#         self.initUI()


#     def initUI(self):

#         self.setMinimumSize(1, 30)
#         self.value = 75
#         self.num = [75, 150, 225, 300, 375, 450, 525, 600, 675]


#     def setValue(self, value):

#         self.value = value


#     def paintEvent(self, e):

#         qp = QPainter()
#         qp.begin(self)
#         self.drawWidget(qp)
#         qp.end()


#     def drawWidget(self, qp):

#         MAX_CAPACITY = 700
#         OVER_CAPACITY = 750

#         font = QFont('Serif', 7, QFont.Light)
#         qp.setFont(font)

#         size = self.size()
#         w = size.width()
#         h = size.height()

#         step = int(round(w / 10))


#         till = int(((w / OVER_CAPACITY) * self.value))
#         full = int(((w / OVER_CAPACITY) * MAX_CAPACITY))

#         if self.value >= MAX_CAPACITY:

#             qp.setPen(QColor(255, 255, 255))
#             qp.setBrush(QColor(255, 255, 184))
#             qp.drawRect(0, 0, full, h)
#             qp.setPen(QColor(255, 175, 175))
#             qp.setBrush(QColor(255, 175, 175))
#             qp.drawRect(full, 0, till-full, h)

#         else:

#             qp.setPen(QColor(255, 255, 255))
#             qp.setBrush(QColor(255, 255, 184))
#             qp.drawRect(0, 0, till, h)


#         pen = QPen(QColor(20, 20, 20), 1, 
#             Qt.SolidLine)

#         qp.setPen(pen)
#         qp.setBrush(Qt.NoBrush)
#         qp.drawRect(0, 0, w-1, h-1)

#         j = 0

#         for i in range(step, 10*step, step):

#             qp.drawLine(i, 0, i, 5)
#             metrics = qp.fontMetrics()
#             fw = metrics.width(str(self.num[j]))
#             qp.drawText(i-fw/2, h/2, str(self.num[j]))
#             j = j + 1


# class Example(QWidget):

#     def __init__(self):
#         super().__init__()

#         self.initUI()


#     def initUI(self):      

#         OVER_CAPACITY = 750

#         sld = QSlider(Qt.Horizontal, self)
#         sld.setFocusPolicy(Qt.NoFocus)
#         sld.setRange(1, OVER_CAPACITY)
#         sld.setValue(75)
#         sld.setGeometry(30, 40, 150, 30)

#         self.c = Communicate()        
#         self.wid = BurningWidget()
#         self.c.updateBW[int].connect(self.wid.setValue)

#         sld.valueChanged[int].connect(self.changeValue)
#         hbox = QHBoxLayout()
#         hbox.addWidget(self.wid)
#         vbox = QVBoxLayout()
#         vbox.addStretch(1)
#         vbox.addLayout(hbox)
#         self.setLayout(vbox)

#         self.setGeometry(300, 300, 390, 210)
#         self.setWindowTitle('Burning widget')
#         self.show()


#     def changeValue(self, value):

#         self.c.updateBW.emit(value)        
#         self.wid.repaint()


# if __name__ == '__main__':

#     app = QApplication(sys.argv)
#     ex = Example()
#     sys.exit(app.exec_())


版权声明:本文为qq_41579723原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。