PyQt5的安装

简介

Qt :跨平台UI工具,用于开源软件,可以用自由软件协议GPL

PyQt :是Qt为python提供的GUI扩展,实现了一个模块集,用python语言实现、封装了Qt所有的类,理论上讲Qt能开发的,PyQt也可以开发。PyQt5使用GPL自由软件协议。

GPL协议:软件版权属于开发者本人,软件产品受国际相关版权法保护。允许其他用户对原作者的软件进行复制或发行,并且可以在更改之后发行自己的的软件。但新软件在发布时也必须遵守GPL协议,不得对其进行附加限制。在GPL下不存在盗版一说,但用户不能将软件据为己有,比如申请软件产品专利等,因为这将违反GPL协议并且侵犯了原作者的版权。

开源许可的区别(转载)

开源许可的区别

PyQt5安装

#安装PyQt5,  -i 使用豆瓣/阿里云提供的镜像
pip install PyQt5 -i https://pypi.douban.com/simple
pip install pillow -i https://mirrors.aliyun.com/pypi/simple/
也可以到https://pypi.douban.com/simple/pyqt5 直接下载需要版本的whl文件,离线安装
永久修改:在c:\users 当前用户创建目录pip,新建pip.ini 
内容如下:(阿里云源)
[global]
index-url = http://mirrors.aliyun.com/pypi/simple/ 
[install]
trusted-host = mirrors.aliyun.com

安装工具,如Qt Designer。不同的tools匹配的pyqt5版本有要求,不匹配时会下载匹配的版本,安装时卸载不匹配的版本
pip install PyQt5-tools -i https://pypi.douban.com/simple

一般tools安装在 python_path\lib\site-packages, 将路径 ..\pyqt5-tools添加到环境变量Path中


#### 安装后的测试
* 创建一个文件 qtui_test.py
```python
import sys
from PyQt5.QtWidgets import QApplication, QWidget,QPushButton

def show_w():
    app = QApplication(sys.argv)   # ([])
    w = QWidget()
    w.resize(500,300)
    w.setWindowTitle('测试窗口')
    btn = QPushButton('BUtton',w)
    btn.resize(100,50),
    btn.move(w.width() - 120,w.height() - 60)
    w.show()
    sys.exit(app.exec_())

if __name__ == '__main__':
    show_w()

运行测试文件

python qtui_test.py

看到下面的窗口,恭喜,安装成功
测试运行结果

UI文件编译为py文件

pyuic5 -o destination.py source.ui
  1. 窗口放置到屏幕中间
class Winform(QMainWindows):
  def __init__(self,parent=None):
  super(WInform,self).__init__(parent)  #关于supper(离自己最近的父类或平辈类,)
  self.resize(300,400)
  self.center()

  def center(self):
    screen = QDesktopWidget().screenGeometry()
    size = self.geometry()
    self.move((screen.width()-size.width())/2,(screen.height()-size.height())/2)
  1. 使用资源
    创建资源文件
<RCC>
  <qresource prefix="pic">
  </qresource>
</RCC>

在Qt Designer中打开,添加相关资源。
编译成.py文件

pyrcc5 apprcc.qrc -o apprcc_rc.py

使用资源文件

#导入资源文件
import apprcc_rc

......
self.label.setText("")
self.label.setPixmap(QtGui.QPoxmap(":/pic/images/sample.jpg"))
  1. 窗口尺寸常用操作
#改变客户区大小
QWidget.resize(width,height) 
QWidget.resize(QSize)
#获取客户区大小,位置
QWidget.size()
QWidget.width()  / height()
.x()  .y() 
#设置客户区固定大小,不可更改
.setFixedWidth(int width) / .setFixedHeight(int height) #固定高或宽
.setFixedSize(int width , int height) # 固定高宽
#包含边框的
#获取窗口大小位置
QWidget.frameGeometry()
#设置窗口位置
QWidget.move(int x, int y)   
QWidget.move(QPoint point)
  1. 创建主窗体
# -*- coding: UTF-8 -*-
import sys
from PyQt5.QtWidgets import QApplication ,QWidget
from PyQt5.QtGui import QIcon

#每个PyQt5程序需要一个QApplication对象,
app = QApplication(sys.argv)  
window = QWidget()
window.resize(300,200)
window.move(250,150)
window.setWindowTitle('Hello')
window.setWindowIcon(QIcon('./images/wicon.icon'))  #设置图标 路径为相对或绝对路径
window.show()
sys.exit(app.exec_())  # 进入程序主循环 运行成功返回0 否则非0
  1. QLabel
    显示不可编辑的文本或图片或GIF,也可以作为伙伴buddy作为其他空间的提示标记,文本可以是纯文本、连接或富文本。
    QObject - QPaintDevice - QWidget - QFrame - QLable
方法 描述
setAlignment() 对齐:Qt.AlignLeft, ..Right,Center,Justify(两端对齐),Top,Bottom,VCenter
setIndent() 文本缩进
setPixmap() 设置QLabel为一个Pixmap图片
text() 获得QLabel的文本内容
setText() 设置QLabel内容
selectedText() 返回已选择的字符
setBuudy() 设置QLabel的助记符及buddy,即使用QLabel设置快捷键,按键后焦点落在其buddy上,buddy可以是任何一个Widget控件
setWordWrap() 设置是否允许换行

常用信号
linkActivated : 单击超连接,setOpenExternalLinks = True
linkHovered: 鼠标滑过超链接。

label.setText("<a href='http://www.xxx.com'>欢迎访问xxx</a>")
label.linkHovered.connect( link_hovered )
label.linkActiveated.connect( link_clicked )

def link_hovered():
  print("hovered")
  1. QLineEdit
    输入单行文本类控件,输入多行用QTextEdit.
方法 描述
setAlignment() 与QLabel一样
clear() 清空内容
setEchoMode() 设置文本框显示格式 QLineEdit.Normal 正常显示;NoEcho 不显示任何内容;Password 显示密码掩码;PasswordEchoOnEdit 编辑时显示字符
setReadOnly() 只读
setText(),Text() 设置,获取文本
setValidator() 校验输入,QintValidator 输入整数,QDoubleValidator 浮点,QRegexpValidator 符合正则表达式
其他 setDragEnabled(),setMaxLength(),SelectAll(),setFocus(),setInputMask()设置掩码

常用信号
selectionChanged: 选择改变了
textChanged: 文本内容变化
editingFinished: 编辑结束

掩码

字符 含义
A ASCII字母是必须输入的(A-Z,a-z)
a ASCII字母允许输入,不是必须的
X 任何字符都是必须的
x 任何字符都是允许输入的,不是必须的
9 数字必须输入
0 数字允许输入,不是必须的
D 1-9必须输入
d 1-9允许输入,非必须
# 数字或+ - 允许输入非必须
H 十六进制必须输入
h 十六进制允许输入
B,b 二进制
> 所有字母大写
< 所有字母小写
! 关闭大小写转换

示例:
000.000.000.000;_ IP地址,空白字符是_
HH:HH:HH:HH:HH:HH MAC地址
000-00-00 日期,空白字符是空格

AAAA-AAAA-AAA;# 空白字符是#,所有字母大写

pIntValidator = QintValidator(self)
pIntValidator.setRange(1,99)

pDoubleValidator = QDoubleValidator(self)
pDoubleValidator.setRange(-360,360)
pDoubleValidator.setNotation(
QDoubleValidator.StandardNotation)
pDoubleValidator.setDecimals(2)

reg = QRegExp("[a-zA-Z0-9]+$")
pValidator = QRegExpValidator(self)
pValidator.setRegExp(reg)

pIntLineEdit.setValidator(pIntValidator)
...
  1. QTextEdit
    多行文本框,可显示文本或HTML文档
方法 描述
setPlainText() 设置内容
toPlainText() 返回文本内容
setHtml() 设置内容为Html
toHtml() 返回多行文本的html内容
clear() 清空
  1. QAbstrctButton
    按钮类的基类,抽象类。
    状态标记:isDown(),isChecked(),isEnable(),isCheckAble(),setAutoRepeat()长按时是否重复执行。
    信号:Pressed, Released, Clicked, Toggled 标记状态变化`

  2. QPushButton

方法 描述
setCheckable() 设置按钮是否已被选中,如果设置为True,标识按钮将保持已点击或释放状态
toggle() 在按钮状态间切换
setIcon() 设置图标
setEnabled() 按钮是否可用
isChecked() 返回按钮状态True False
setDefault() 设置按钮默认状态
setText() 设置按钮显示文本
text() 返回按钮显示文本
  1. QRadioButton
    单选按钮,多个按钮放入一个QGroupBox或QButtonGroup中,一次只能选一个。
    主要方法:setCheckable(), isChecked(), setText(), text()
    toggled信号在切换按钮状态时发射,clicked信号在每次点击否会发射,实际使用中,用toggled信号监控状态。

  2. QcheckBox
    多选框,在状态变化时会发射一个stateChanged信号,isChecked查询是否被选中。还有第三种状态,“半选中”,标识状态没有变化,用setTristate()使他生效,使用checkState()来查询当前的切换状态。
    主要方法:setChecked(), setText(), text() , isChecked(), setTriState()
    三种状态:Qt.Checked 2,选中默认, Qt.PartiallyChecked 1 半选中 Qt.Unchecked 0 未选中

  3. QcomboBox
    下拉列表框。

方法 描述
addItem() 添加一个下拉项
addItems() 从列表添加下拉选项
Clear() 删除所有选项
count() 选项数目
currentText() 返回选中文本
itemText(i) 索引为i的文本
currenIndex() 选中项索引
setItemText(int index,text) 设置序号为index项的文本

信号
Activated : 选中一个下拉选项时
currentIndexChanged: 下拉索引发生改变
highlighted: 选中一个已选中的下拉选项

  1. QDialog
    包括QMessageBox,QFileDialog、QFontDialog、QInputDialog等
    方法:
    setWindowTitle(),
    setWindowModality() Qt.NonModal 非模态可与其他窗口交互 WindowModal 窗口模态 阻止与父窗口交互 ApplicationModal 应用程序模态,阻止和任何其他窗口交互
  • QMessageBox
方法 描述
information(QWidget parent,title,text,buttons,defaultButton) 弹出消息对话框。parent 父窗口控件,title 标题 text 消息文本 buttons 多个标准按钮,默认Ok按钮,defaultButton,默认选中按钮
question(parent,title,text,buttons,defaultButton) 同上
warming(parent,title,text,buttons,defaultButton) 同上
about(parent ,title,text) 同上
setTitle() 设置标题
setText() 设置消息正文
setIcon() 弹出对话框的图片

标准按钮类型

按钮 描述
QMessage.OK OK
QMessage.Cancel Cancel
QMessage.Yes
QMessage.No
QMessage.Abort
QMessage.Retry
QMessage.Ignore

使用示例

reply = QMessageBox.information(self,'Title','Text',QmessageBox.Yes|QMessageBox.No,QMessageBox.Yes)
  • QInputDialog
    由文本框和OK Cancle组成,可输入数字,字符串,或列表选项。
方法 描述
getInt() 从控件中输入整数
getDouble() 浮点
getText() 字符串
getItem() 列表选项

使用示例

items = ('a','b','c','d','e')
text,ok=QInputDialog.getItem(self,'selct item','列表值',items,0,False)
if ok and item:
  self.lineedit.setText(item)
  • QFontDialog
font, ok = QFontDialog.getFont()
if ok:
  self.fontLineEdit.setFont(font)
  • QFileDialog
方法 描述
getOpenFileName() 返回用户选择的文件名,打开文件
getSaveFileName() 使用用户选择文件名,保存文件
setFileMode() QFileDialog.AnyFile,任意文件;ExistingFile已存在的文件;Directory 文件目录;ExistingFiles 已存在的多个文件
setFilter() 过滤器,显示允许的文件类型
fname, _ = QFileDialog.getOpenFileName(self,'OpenFile','C:\\',"Image files(*.jpg *.gif)")
self.label.setPixmap(QPixmap(fname))

def getfiles(self):
  dlg = QFileDialog()
  dlg.setFileMode(QFileDialog.AnyFile)
  dlg.setFilter(QDir.Files)
  if dlg.exec_():
    filenames = dlg.selectedFiles()
    f = open(filenames[0],'r')
    with f:
      data = f.read()
      self.contents.setText(data)
  1. 窗口绘图类控件
    主要包括QPainter、QPen、QBrush
  • QPainter
    在QWidget上执行绘图操作,是一个绘图工具,为大部分图形界面提供了高度优化的函数。
    绘制操作在QWidget.paintEvent()中完成。绘制方法必须放在QtGui.QPainter对象的begin()和end()之间。
方法 描述
begin() 开始在目标设备上绘图
drawArc() 在其实角度和最终角度之间画圆弧
drawEllipse() 在一个矩形区域内画一个椭圆
drawLine(x,y,x,y) 绘制直线,并设置当前画笔位置在后一个点
drawPixmap() 从图形文件中提取pixmpa并显示在指定位置
drawPolygon() 使用坐标数组绘制多边形
drawRect(x,y,w,h) x,y画一个w,h的矩形
drawText() 显示给定坐标处的文字
fillRect() 使用QColor参数填充矩形
setBrush() 设置画笔风格
setPen() 画笔的颜色、大小和样式

画笔风格PenStyle

类型 描述
Qt.NoPen 无线条,如QPainter.drawRect()填充,但没有边界
.SolidLine 单线条
.Dahsline 虚线
.DotLine 点划线
.DashDotLine 虚点划线
.DashDotDotLine
.MpenStyle 画笔风格的掩码
class Drawing(QWidget):
  def __init__(self,parent=None):
    super(Drawing,slef).__init__(parent)
    self.setWindowTitle('Drawing')
    self.resize(300,200)
    self.text  = '输出文字' 
 
 # 所有绘制方法都在绘制事件中发生,必须在begin和end之间
  def paintEvent(slef,event):
    painter = QPainter(self)
    painter.begin(self)
    self.drawText(event,painter)
    painter.end()

  # 输出文字
  def drawText(self,event,qp):
    qp.setPen(QColor(168,36,22))  # Qt.red
    qp.drawText(event.rect(),Qt.AlignCenter,self.text)

#用点绘制正弦曲线
def drawPonts(self,qp):
  qp.setPen(Qt.red)
    
  for i in range(1000):
    x = 100 * (-1+2.0*i/1000)
    y = -50*math,sin((x-size.width()/2.0)*math.pi/50)
    qp.drawPont(x,y)

if __name__ == "__main__":
  app = QApplication(sys.argv)
  dr = Drawing()
  dr.show()
  sys.exit(app.exec_())
  • QPen
    基本图形对象,用于绘制直线,曲线或矩形,椭圆,多边形及其他形状
pen = QPen(Qt.black, 2, Qt.SolidLine)
pen.setStyle(Qt.CustomDashLine)
pen.setDashPattern([1,4,5,4])
qp.setPen(pen)
qp.drawLine(....)

  • QBrush
    基本图形对象,用于填充如矩形,椭圆或多边形。QBrush有三种类型:预定义、过渡和纹理图案。
brush = QBrush(Qt.SolidPattern)
qp.setBrush(brush)
qp.drawRect(....)
  • QPixmap
    绘制图形,可以作为一个QPaintDevice对象,也可以加载到一个控件中,通常是标签或按钮。可读取类型BMP GIF JPG JPEG PNG PBM PGM PPM XBM XPM等
方法 描述
copy() 从QRect对象复制到QPixmap对象
fromImage() 将QImage对象转为QPixmap对象
grabWidget() 从给定的窗口小控件创建一个像素图
grabWindow() 在窗口中创建数据的像素图
load() 加载图像文件作为QPixmap对象
save() 将QPixmap对象另存为文件
toImage() 将QPixmap对象转为QImage对象
  1. QDrag
  2. QClipboard
  3. QCalendar
  4. QDateTimeEdit
  5. 菜单、工具栏和状态栏
  • QStatusBar
self.statusBar = QStatusBar()
self.setStatusBar(self.statusBar)

方法|描述
|---|---|
addWidget()|在状态栏中添加给定的窗口小控件对象
addPermanentWidget()|在状态栏中永久添加给定的窗口小控件
showMessage()|在状态栏显示一条临时信息,显示指定时间时长
clearMessage()|删除临时显示的信息
removeWidget()|从状态栏中删除指定的小控件

20. QPrinter
打印图像,实际上是QPaintDevice中画图,与在QWidget、QPixmap和QImage中画图一样,创建一个QPainter对象进行画图,知识打印使用的是QPrinter。

21. 表格和树
* QTableView
一批数据进行交互,以表格输出,可以使用自定义的数据模型来显示内容,通过setModel来绑定数据。
QTableWidget继承自QTaleView,主要区别是QTableView可以使用自定义的数据模型来显示内容(先通过setModel来绑定数据源),而QTableWidget只能使用标准数据。且单元格数据是通过QTableWidgetItem对象来实现的。
QTableView可用模式如下

名称|说明
|---|---|
QStringListModel| 字符串
QStandardItemModel|任意层次结构的数据
QDirModel|文件系统进行封装
QSqlQueryModel|对SQL查询结果集进行封装
QSqlTableModel|对SQL表格进行封装
QSqlRelationTableModel|对带有foreign key的SQL表格进行封装
QSortFilterProxyModel|对模型中的数据进行排序或过滤

* QListView

*QTreeView
QWidget - QFrame - QAbstractScrollArea- QAbstractItemView - QTreeView - QTreeWidget
QTreeWidget常用方法

方法|描述
|---|---|
setColumnWidth(int column,int width)|将指定列的宽度设为给定值
insertTopLevelItems()|在试图的顶层索引中插入项目列表
expandAll()|展开所有节点
invisibleRootItem()|返回树形控件中不可见的根选项
selectedItems()|返回所有选定的非隐藏项目的列表

QTreeWidgetItem常用方法

方法|描述
|---|---|
addChild()|将子项追加到子列表中
setText()|设置显示的节点文本
Text()|返回显示的节点文本
setCheckState(column,state)|设置指定列的选中状态 Qt.Checked, UnChecked
setIcon(column,icon)|在制定的列表中显示图标

```python
self.tree = QTreeWidget()
self.tree.setColumnCount(2)
self.tree.setHeaderLabels(['key','value'])

#根节点
root = QTreeWidgetItem(self.tree)
root.setText(0,'root')
root.setIcon(0,QIcon("./images/root.png"))
#设置树形控件宽度
self.tree.setColumnWidth(1,160)

#设置子节点1
child1 = QTreeWidgetItem(root)
child1.setText(0,'child1')
child1.setText(1,'chiild1 col2')
child1.setIcon(0,QIcon("./images/xx.png"))

......其他节点
self.tree.addTopLevelItem(root)
self.tree.expandAll()

#也可以用以下方法添加
root = QTreeWidgetItem()
root.setText(0,'root')

rootList = []
rootList.append(root)

child1 = QTreeWidgetItem()
child1.setText(0,'child1')
child1.setText(1,'xxx')
root.addChild(child1)

self.tree.insertTopLevelItems(0,rootList)

# 设置节点状态
child1.setCheckState(0,Qt.Checked)

self.tree.clicked.connect(self.onTreeClicked)
def onTreeClicked(self,qmodeindex):
  item = self.tree.currentItem()
  print("key=%s,value=%s" %(item.text(0), item.text(1)))

系统定制模式

model  = QDirModel()
tree = QTreeView()
tree.setModel(model)
tree.resize(300,400)
tree.show()
  1. 容器
  • QTabWidget
  • QStackWidget
  • QDockWidget
  1. 多线程
  • 事件处理
    processEvents()在一些卡顿耗时的循环中使用QApplication.processEvents(),刷新页面。
    *网页交互
    QWebEngineView 加载显示外部web页面
    调用JavaScript代码。QWebEnginePage.runJavaScript(str,Callable)
    JavaScript调用pyqt代码
  1. 布局管理
#布局计算器的例子
grid = QGridLayout()
self.setLayout(grid)

names = ['Cls','Back','','Close',
            '7','8','9','/',
            '4','5','6','*',
            '1','2','3','-',
            '0','.','=','+']
positions = [(i,j) for i in range(5) for j in range(4)]
for postion,name in zip(positions,names):
  if name == '' :
    continue
  button = QpushButton(name)
  grid.addWidget(button, *position)

  1. 信号signal和槽slot
    signal和slot是Qt中的核心机制,也是PyQt对象之间通讯的机制。每一个QObject对象和PyQt中继承制自QWidget的控件(这些都是QObject的子对象)都支持信号和槽。通过object.signal.connect()连接。
  • 一个信号可以连接多个槽
  • 一个信号可以连接另一个信号
  • 信号参数可以是任何Python类型
  • 一个槽可以监听多个信号
  • 信号与槽的连接可以是同步,也可以是异步
  • 信号与槽的连接可以跨线程
  • 信号与槽可以断开

为QObject对象创建信号:
使用pyqtSignal()函数创建一个或多个重载的未经绑定的信号作为类的属性,信号只能在QObject的子类中定义。
信号必须在类创建时定义,不能在类创建后作为类的属性动态添加进来。
使用pyqtSignal()函数创建信号时,信号可以传递多个参数,并制定信号传递参数的类型,可以是 字符串,日期,bool,数字,列表,元组,字典。

定义:
class xx(QObject):
valueChanged = pyqtsignal([dict],[lisst])

  • 使用内置信号与槽的使用
  • 自定义信号与槽
    不适用控件函数,使用自定义的函数。可以自定义传递参数。
from PyQt5.QtCore import QObject,pyqtSignal
class QTypeSingal(QObject)
#定义信号
  sendmsg = pyqtSignal(object)
  def __init__(self):
    super(QTypeSignal,self).__init__()
  def run(self):
    self.sendmsg.emit('hello pyqt5')
#定义槽
class QTypeSlot(QObject):
  def __init__(self):
    super(QTypeSlot,self).__init__()
  def get(self,msg):
    print(msg)

if __name__ == '__main__':
  send = QTypeSinal()
  slot = QTypeSlot()
  send.sendmsg.connect(slot.get)
  send.run() #运行发射信号

装饰器信号与槽
通过装饰器的方法定义信号和槽函数。具体使用方法如下:

@PyQt5.QtCore.pyqtSlot(参数)
def on_发送对象名称_发射信号名称(self, 参数):
   .....

self.okButton.setObjectName("okButton")
QtCore.QMetaObject.connectSlotsByName(self)

@QtCore.pyqtSlot()
def on_okButton_clicked(self):
  print(' 单击了OK‘)
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,491评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,856评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,745评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,196评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,073评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,112评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,531评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,215评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,485评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,578评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,356评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,215评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,583评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,898评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,497评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,697评论 2 335