11月 14

pyinstaller打包的pyside程序无法运行可能原因

缺少必要的dll文件

目录:
C:\Users\shuch\anaconda3\envs\MusculoskeletalModeling\Library\plugins\platforms
其中包含qt运行所必要的dll文件

gif,jpg等图片无法正常加载

静态图片还是转换成png格式吧。经过反复测试,就算额外导入图片相关的qjpeg.dll仍然不能显示。可能是有什么bug
动态图片可以导入文件夹:
C:\Users\shuch\anaconda3\envs\MusculoskeletalModeling\Library\plugins\imageformats

11月 1

QSS之声明

盒子模型

控件可以分为:margin,border,padding和content四部分。这个模型成为盒子模型。值得注意的是,resize控制的是整个盒子模型的尺寸。

border边框设置

边框。可以设置的项目包括宽度,样式和颜色。可以在border中统一进行设置

border-width边框宽度

可以传入一个值,表示各边设置成同样的宽度,也可以传入两个值,分别为上下,和左右,还可以传入四个值,分别为上右下左。需要写上单位,例如px

border-top-width等

单独设置某一侧的边框宽度。如上面的例子

border-style边框样式。

可以传入一个值,表示各边设置成同样的样式,也可以可以传入四个值,分别是上右下左边框设置

border-top-style等

单独设置某一侧的边框样式。如上面的例子

可以设置的样式举例

  • none
  • dotted
  • solid
  • dashed
  • double
  • ...

    border-color边框颜色

    可以传入一个值,表示各边设置成同样的颜色,也可以传入两个值,分别为上下,和左右,还可以传入四个值,分别为上右下左。需要写上单位,例如px

    border-top-color等

    单独设置某一侧的边框颜色。如上面的例子

    可以设置的颜色举例

  • red
  • rgb(100,100,100)
  • 00ff00

  • 渐变颜色

    border-image

    用一张图片设置边框示

    border-width: 30px
    border-image: url(../source/border_image.png) 30px 30px 30px 30px stretch;

    margin外边距设置

    可以传入一个值,表示各边设置成同样的外边距,也可以可以传入四个值,分别是上右下左外边距设置

    margin-left

    左边距,类似的有左右上下的边距

    padding内边距设置

    可以传入一个值,表示各边设置成同样的内边距,也可以可以传入四个值,分别是上右下左内边距设置

    padding-left

    左边距,类似的有左右上下的边距

    background背景

    可统一设置多个值。类似border属性的统一设置

    background-color

    背景颜色

    background-image

    背景图片

    background-repeat

    背景图片是否重复

  • no-repeat
  • repeat-x
  • repeat-y
  • repeat-xy(默认)

    background-position

    图片放置位置

  • top
  • bottom
  • left
  • right

    background-origin

    参照位置

  • padding(默认)
  • border
  • margin
  • content

    background-clip

    裁剪策略

  • padding(默认)
  • border
  • margin
  • content

    background-attachment

    背景是否随着内容移动

  • scroll
  • fixed

    字体 font

  • 字体家族 font-family
  • 字体尺寸 font-size
  • 字体样式 font-style
  • 字体权重(加粗)font-weight
  • 颜色 color

    设置最大最小尺寸

  • 最小宽度 min-width
  • 最小高度 min-height
  • 最大宽度 max-width
  • 最大高度 max-height

    前景图片 image

    子控件相对父控件位置

  • subcontrol-origin
  • subcontrol-position
  • position: relative 和 position: absolute
  • 位置微调 top,bottom,left,right
11月 1

QSS之标签选择器

选择器

注意:

通过 控件.setStyleSheet('...')来设置的,子控件会继承设置的效果
而通过下面讲解的选择器进行设置的,子控件不会继承设置的效果

通配符选择器:*

匹配所有控件,一般用于全局控制

类型选择器:QWidget

匹配当前类型以及所有子类。例如我们设置QWidget时,也会QPushButton一起设置。

类选择器:.QPushButton

在类型选择器前面加一个.,与类型选择器的不同在于,类选择器只会选择设置当前选择的类,不会对子类进行设置

ID选择器:#objectName

通过对象所设置的objectName属性来进行样式的设置

属性选择器:QWidget[notice_level='error']

根据对象所设置的property属性来进行样式的设置

后代选择器: QDialog QPushButton

通过对象的父子关系(注意不是类的继承关系)来选择。上面的例子就是选择所有Dialog类型中的QPushButton。无论是直接包含还是间接包含,都可以选中。

子选择器: QDialog>QPushButton

通过对象的父子关系(注意不是类的继承关系)来选择。上面的例子就是选择所有Dialog类型中的QPushButton。只匹配直接包含

子控件选择器: QCheckBox::indicator

在CheckBox或者RadioButton等复合控件中,可以单独选中某一个子控件。

伪状态选择器:QCheckBox:Checked

用于标记控件的某种特定状态,例如按钮按下,单选框选中等。

并列选择器:QLabel,QPushButton

表示对逗号前后两个选择的对象同时进行设置。

8月 25

QObject计时器案例(二)

import sys
from PySide2 import QtWidgets as qtw
from PySide2 import QtCore as qtc

class MyWidget(qtw.QWidget):

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.resize(100, 100)
        self.timer_id = None

    def start_timer(self, time):
        self.timer_id = self.startTimer(time)

    # 重写timerEvent方法
    def timerEvent(self, event):
        current_width = self.width()
        current_height = self.height()
        current_width += 10
        current_height += 10
        self.resize(current_width, current_height)
        if current_width > 500 or current_height > 500:
            self.killTimer(self.timer_id)

app = qtw.QApplication()

window = MyWidget()
window.start_timer(500)

window.show()
sys.exit(app.exec_())
8月 25

QObject计时器案例

import sys
from PySide2 import QtWidgets as qtw
from PySide2 import QtCore as qtc

class MyLabel(qtw.QLabel):

    def __init__(self, *args, **kwargs):
        super(MyLabel, self).__init__(*args, **kwargs)
        self.setText('10')
        self.move(225, 225)
        self.setStyleSheet('font-size: 30px;')
        self.label_timer_id = self.startTimer(1000)

    # 重写timerEvent方法
    def timerEvent(self, event):
        current_time = int(self.text())
        current_time -= 1
        self.setText(str(current_time))

        if current_time == 0:
            self.killTimer(self.label_timer_id)

app = qtw.QApplication()

window = qtw.QWidget()
window.resize(500, 500)

label = MyLabel(window)

window.show()
sys.exit(app.exec_())
8月 25

QObject计时器

import sys
from PySide2 import QtWidgets as qtw
from PySide2 import QtCore as qtc

class MyObject(qtc.QObject):

    # 重写timerEvent方法,就是当定时器经过指定时间后执行的方法
    def timerEvent(self, event):
        print(event, 1)

app = qtw.QApplication()

window = qtw.QWidget(None)
window.resize(800, 800)

obj = MyObject()
# 开始定时器,设置每1000ms执行一次timerEvent方法
# timer_id可以用来killTimer(timer_id)
# startTimer方法的第二个参数为设置计时器的精度
timer_id = obj.startTimer(1000, qtc.Qt.CoarseTimer)

# 关闭timer_id对应的计时器
obj.killTimer(timer_id)

window.show()

sys.exit(app.exec_())
8月 25

Qt的事件机制(一)

import sys
from PySide2 import QtWidgets as qtw
from PySide2 import QtCore as qtc

def pressed_slot():
    print('按钮被点击了-slot')

# 为了查看QApplication.notify(receiver, event)的方法
# 我们进行方法的override
class App(qtw.QApplication):

    # arg__1为receiver,arg__2为event
    def notify(self, arg__1, arg__2):
        # 判断receiver为QPushButton的子类,同时判断event的类型为qtc.QEvent.MouseButtonPress
        if arg__1.inherits('QPushButton') and arg__2.type() == qtc.QEvent.MouseButtonPress:
            print('receiver: ', arg__1)
            print('event: ', arg__2)

        return super(App, self).notify(arg__1, arg__2)

# 为了查查看receiver.event(event)方法
# 我们进行方法的override
class Btn(qtw.QPushButton):

    # e 为接收的event
    def event(self, e):
        # 注意判断event的类型需要用event.type()方法
        if e.type() == qtc.QEvent.MouseButtonPress:
            print('按钮被点击了-receiver.event')

        return super(Btn, self).event(e)

    # 由event方法分发的具体事件处理方法
    # 信号就在这些具体事件处理方法中发射
    def mousePressEvent(self, e):
        print('鼠标被按下了-具体的分发函数')

        return super(Btn, self).mousePressEvent(e)

app = App()

window = qtw.QWidget()

btn = Btn(window)
btn.setText('点我')
btn.move(100, 100)

btn.pressed.connect(pressed_slot)

window.show()

sys.exit(app.exec_())
8月 24

QObject对象删除

import sys
from PySide2 import QtWidgets as qtw
from PySide2 import QtCore as qtc

app = qtw.QApplication()

obj1 = qtc.QObject(None)
obj2 = qtc.QObject(obj1)
obj3 = qtc.QObject(obj2)

obj1.destroyed.connect(lambda: print('obj1被释放了'))
obj2.destroyed.connect(lambda: print('obj2被释放了'))
obj3.destroyed.connect(lambda: print('obj3被释放了'))

# 直接使用del进行删除,如果这个对象有父对象,则删除不了
# 但是用deleteLater方法就可以将有父对象的对象直接删除
obj2.deleteLater()
# deleteLater不会立即执行,而是要等到下一个消息循环再删除
print(obj1.children())

sys.exit(app.exec_())
8月 24

QObject类型判定案例

import sys
from PySide2 import QtWidgets as qtw

app = qtw.QApplication()

window = qtw.QWidget()
label_1 = qtw.QLabel(window)
label_1.setText('安静一键宏')

label_2 = qtw.QLabel(window)
label_2.setText('轻松玩魔兽')
label_2.move(0, 30)

btn = qtw.QPushButton(window)
btn.setText('点我')
btn.move(0, 60)

# .children() 方法只是返回所有的子对象,没有findChildren的过滤功能
for item in window.children():
    if item.inherits('QLabel'):
        item.setStyleSheet('background-color: red;')

window.show()

sys.exit(app.exec_())
8月 24

QObject类型判定

import sys
from PySide2 import QtWidgets as qtw
from PySide2 import QtCore as qtc

app = qtw.QApplication()

obj = qtc.QObject()
widget = qtw.QWidget()
btn = qtw.QPushButton()
label = qtw.QLabel()

items = [obj, widget, btn, label]

for item in items:

    print('============================')
    # 判断对象是否为控件(widget)类型
    print('是否为控件:', item.isWidgetType())
    # inherits包含了直接继承和间接继承
    # inherts接收的参数为类名,如下所示:
    print('是否继承自QWidget:', item.inherits('QWidget'))
    print('是否继承自QPushButton:', item.inherits('QPushButton'))
    print('============================')

sys.exit(app.exec_())