QT學習記錄

學習進度

week3:
QStringListModel(modelview類)钳吟。model更新時自動更新view汉操。
圖片.png

mylistview.h

#ifndef MYLISTVIEW_H
#define MYLISTVIEW_H

#include<QWidget>
#include<QStringListModel>
#include<QListView>
#include<QHBoxLayout>
#include<QPushButton>
#include<QLineEdit>
#include<QModelIndex>
#include<QMessageBox>
#include<QInputDialog>
class MyListView : public QWidget
{
    Q_OBJECT

public:
    MyListView();
private:
    QStringListModel *model;
    QListView *listView;
private slots:
    void insertData();
    void deleteData();
    void showData();
};
#endif // MAINWINDOW_H

mylistview.cpp

#include "mylistview.h"

MyListView::MyListView()
{
    model=new QStringListModel(this);//創(chuàng)建model對象
    QStringList data;//設置model數(shù)據(jù)
    data<<"Letter A"<<"Letter B"<<"Letter C";
    model->setStringList(data);//把數(shù)據(jù)設置為model的數(shù)據(jù)
    listView=new QListView(this);
    listView->setModel(model);//view和model綁定

    QHBoxLayout *btnLayout=new QHBoxLayout;
    QPushButton *insertBtn=new QPushButton(tr("insert"),this);
    QPushButton *delBtn=new QPushButton(tr("delete"),this);
    QPushButton *showBtn=new QPushButton(tr("show"),this);
    btnLayout->addWidget(insertBtn);
    btnLayout->addWidget(delBtn);
    btnLayout->addWidget(showBtn);//添加下方按鈕

    QVBoxLayout *mainLayout=new QVBoxLayout(this);
    mainLayout->addWidget(listView);
    mainLayout->addLayout(btnLayout);
    this->setLayout(mainLayout);//全局

    connect(insertBtn,SIGNAL(clicked()),this,SLOT(insertData()));
    connect(delBtn,SIGNAL(clicked()),this,SLOT(deleteData()));
    connect(showBtn,SIGNAL(clicked()),this,SLOT(showData()));
}

void MyListView::insertData()
{
    bool isOK;
    QString text=QInputDialog::getText(NULL,"Insert","Please input new data",QLineEdit::Normal,"you are inserting new data",&isOK);
    if(isOK)
    {
        int row=listView->currentIndex().row();
        model->insertRows(row,1);
        QModelIndex index=model->index(row);
        model->setData(index,text);
        listView->setCurrentIndex(index);
        listView->edit(index);
    }
}

void MyListView::deleteData()

{
    if(model->rowCount()>1)
    {
        model->removeRows(listView->currentIndex().row(),1);//1是在當前行插入的行數(shù)
    }
}

void MyListView::showData()
{
    QStringList data=model->stringList();
    QString str;
    foreach(QString s,data)
    {
        str+=s+"\n";
    }
    QMessageBox::information(this,"DATA",str);
}

main.cpp

#include "mylistview.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MyListView w;
    w.show();
    return a.exec();
}

QTreeWidget(item class)
圖片.png

main.cpp

#include "treewidget.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    TreeWidget w;

    w.show();
    return a.exec();
}

treewidget.cpp

#include "treewidget.h"


TreeWidget::TreeWidget()
{
    tree=new QTreeWidget(this);
    tree->setColumnCount(2);//columnCount是用來在列表中顯示樹的
    QTreeWidgetItem *root=new QTreeWidgetItem(tree,QStringList(QString("Root")));
    QTreeWidgetItem *leaf=new QTreeWidgetItem(root,QStringList(QString("Leaf 1")));
    root->addChild(leaf);
    QTreeWidgetItem *leaf2=new QTreeWidgetItem(root,QStringList(QString("Leaf 1")));
    leaf2->setCheckState(0,Qt::Checked);
    root->addChild(leaf2);
    QList<QTreeWidgetItem *>rootList;
    rootList<<root;
    tree->insertTopLevelItems(0,rootList);
}

treewidget.h

#ifndef TREEWIDGET_H
#define TREEWIDGET_H

#include<QMainWindow>
#include<QWidget>
#include<QTreeWidget>

class TreeWidget : public QWidget
{
public:
     TreeWidget();
private:
      QTreeWidget *tree;
};
#endif // TREEWIDGET_H

QListWidget(itemclass)
圖片.png

main.cpp


#include <QApplication>
#include<QWidget>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    ListWidget lw;
    lw.resize(400,200);
    lw.show();
    return a.exec();
}

listWidget.cpp

#include "listWidget.h"

ListWidget::ListWidget()
{
    label=new QLabel;
    label->setFixedWidth(70);
    list=new QListWidget;
    list->addItem(tr("line"));
    list->addItem(tr("Rect"));
    list->addItem(tr("Oval"));
    list->addItem(tr("Triangle"));
    QHBoxLayout *layout=new QHBoxLayout;
    layout->addWidget(label);
    layout->addWidget(list);
    setLayout(layout);
    connect(list,SIGNAL(currentTextChanged(QString)),label,SLOT(setText(QString)));
}

listWidget.h

#ifndef LISTWIDGET_H
#define LISTWIDGET_H

#include <QWidget>
#include<QLabel>
#include<QListWidget>
#include<QHBoxLayout>


class ListWidget : public QWidget
{
public:
      ListWidget();
private:
      QLabel *label;
      QListWidget *list;
};
#endif // LISTWIDGET_H

Qt model-view

不降低性能的前提下處理大量數(shù)據(jù),可以讓一個model注冊給多個view莺褒。少量數(shù)據(jù)時用item view類捉貌。分別是QList(\Table\Tree)Widget。較大數(shù)據(jù)使用QList(\Table\Tree)view镰官,且需要提供
model。
對接

關(guān)聯(lián)存儲器

存儲二元組映射吗货。QMap<K,T>是key-value數(shù)據(jù)結(jié)構(gòu)泳唠,按k升序進行存儲≈姘幔可用insert或[]插入

QMap<QString,int>map笨腥;
map.insert("test1",1);
map.insert("test2",2);
//或
map["test1"]=1;

而取值時,在非const的map中勇垛,[]取不存在的key值會自動創(chuàng)建一個值為空的key脖母。為避免這種查詢時自動插入,可使用:c++map.value(key);
key不存在時會返回0闲孤,對象類型則會調(diào)用默認構(gòu)造函數(shù)谆级,返回一個對象,不創(chuàng)建新的鍵值對。如果需要不存在的鍵返回默認值肥照,可使用c++int seconds = map.value("delay", 30);
QMultiMap一個key索引多個值脚仔。
QHash<K,T>查找速度更快,存儲不排序舆绎,K類型需被qHash()支持玻侥。可用reverse()函數(shù)擴大散列亿蒸,squeeze()壓縮
遍歷方式:

//【Java風格】next()和previous()函數(shù)可以返回一個鍵值對,而不僅僅是值
QMap<QString,int> map;//創(chuàng)建QMap對象map
QMapIterator<QString,int>i(map)//創(chuàng)建map的迭代器i
while(i.hasNext()) sum+=i.next().value()掌桩;
//Mutable遍歷器可以修改key對應的值边锁,如
i.setValue(-i.value());
//【stl風格】,foreach循環(huán)分別對key和value循環(huán)
QMultiMap<QString,int>map;
foreach(QString key,map.keys())
{
      foreach(int value,map.values(key))
  {
    dosth(key,value);
  }
}
遍歷器

每個容器都有對應的遍歷器波岛。
只讀遍歷器有:QVectorIterator茅坛,QLinkedListIterator和 QListIterator三種;讀寫遍歷器同樣也有三種则拷,只不過名字中具有一個 Mutable贡蓖,即QMutableVectorIterator,QMutableLinkedListIterator和 QMutableListIterator煌茬。
對list或者vector使用at()進行只讀訪問([]既可以是左值也可以是右值斥铺,而at不能作為左值)
盡量使用const_iterator,constBegin()坛善,constEnd()晾蜘,不然在數(shù)據(jù)改變時Qt會進行深復制。
【Java風格遍歷器】
Java風格的遍歷器不指向元素眠屎,而是指向元素間隙剔交。

//從前向后
QList<double>list;
QListIterator<double>i(list);
while(i.hasNext()){doSomethingWith(i.next());}
//從后向前。toBack()指向最后一個元素的后面的位置改衩,用hasPrevious()和previous()函數(shù)遍歷岖常。

【STL遍歷器】
每個順序容器類都有倆遍歷器:C::iterator和C::const_iterator。后者不允許對數(shù)據(jù)修改葫督。begin和end分別指向第一個和最后一個之后的元素竭鞍。容器為空時begin和end相同(或用isEmpty判斷是否為空)。
可以用++--使遍歷器移動橄镜,返回值是指向這個元素的指針笼蛛。

QList<double>::iterator i=list.begin();
while(i!=list.end())
{
  *i=qAbs(*i);++i;
}

如果要使用 STL 風格的遍歷器,并且要遍歷作為返回值的容器蛉鹿,就要先創(chuàng)建返回值的拷貝滨砍,然后進行遍歷(java不用,因為會自動創(chuàng)建拷貝)。
可以通過傳入引用避免對容器的拷貝工作惋戏,防止臨時拷貝占用大量內(nèi)存领追。

順序存儲容器

1.QVector:知道自己長度并且可以改變大小的數(shù)組。如果沒有顯式賦值則自動初始化為0

QVector<double> v(length);
v[pos]=value;//用[]賦值
QVector<double> v;
v.append(value1);
v.append(value1);
QVecor<double>v;//不知道長度响逢,通過append添加
//或使用被重載的<<
v<<value1<<value2;

2.QLinkedList:雙向鏈表绒窑。添加只能用<<和append()
3.QList:除非我們需要進行在很大的集合的中間位置的添加、刪除操作舔亭,或者是需要所有元素在內(nèi)存中必須連續(xù)存儲些膨,否則我們應該一直使用 Qlist。QStringList用來操作QString钦铺,QStack和QQueue則是數(shù)據(jù)結(jié)構(gòu)中的堆棧隊列订雾。
4.模板類的占位符除了基本數(shù)據(jù)類型也可以是指針或者類,如果是類的話需要提供默認構(gòu)造函數(shù)矛洞、拷貝構(gòu)造函數(shù)和賦值操作符洼哎,QObject的子類不符合條件,但是可以通過存儲QObject的指針而不是值實現(xiàn)沼本。也可以容器的容器

QList<QVector<int> > list;//》\>之間的空格不能省略屎媳,防止編譯器把它解析成>>操作符 
week2:
QWidget
Qt Graphics View Framework

Qtpainter是狀態(tài)機饥悴,Graphics View是面向?qū)ο蟮摹VС謱odel對象不同角度的觀察。
line.h

#ifndef LINE_H
#define LINE_H

#include "shape.h"
class Line:public Shape
{
public:
     Line();//構(gòu)造函數(shù)
     void paint(QPainter &painter);//父類的虛函數(shù)持搜,需重寫
};
#endif // LINE_H

rect.h

#ifndef RECT_H
#define RECT_H
#include "shape.h"
class Rect:public Shape
{
public:
        Rect();
        void paint(QPainter &painter);
};
#endif // RECT_H

shape.h

#ifndef SHAPE_H
#define SHAPE_H
#include<QtWidgets>
class Shape
{
public:
        enum Code//枚舉嫌蚤,變量范圍不超過列舉的類型
        {
            Line,
            Rect
        };
        Shape();
        void setStart(QPoint s){start=s;}
        void setEnd(QPoint e){end=e;}
        QPoint startPoint() {return start;}
        QPoint endPoint() {return end;}
        void virtual paint(QPainter & painter)=0;
   protected:
        QPoint start;
        QPoint end;
};



#endif // SHAPE_H

paintwidget.h

#ifndef PAINTWIDGET_H
#define PAINTWIDGET_H

#include<QtWidgets>
#include<QDebug>
#include"shape.h"
#include"line.h"
#include"rect.h"
class PaintWidget : public QWidget
{
    Q_OBJECT
public:
    PaintWidget(QWidget *parent=0);
public slots:
    void setCurrentShape(Shape::Code s)
    {
        if(s!=currShapeCode)
        {
            currShapeCode=s;
        }
    }//if 防止遞歸
protected:
    void paintEvent(QPaintEvent *event);
    void mousePressEvent(QMouseEvent *event);
    void mouseMoveEvent(QMouseEvent *event);
    void mouseReleaseEvent(QMouseEvent *event);
private:
    Shape::Code currShapeCode;
    Shape *shape;
    bool perm;//用來判斷一次繪圖是否結(jié)束
    QList<Shape*>shapeList;//圖形序列
};
#endif // PAINTWIDGET_H

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include<QtGui>
#include<QAction>
#include<QLabel>
#include<QToolBar>
#include<QLabel>
#include<QWidget>
#include<QStatusBar>
#include<QActionGroup>
#include "shape.h"
#include "paintwidget.h"
class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = 0);
signals:
    void changeCurrentShape(Shape::Code newShape);
private slots:
    void drawLineActionTriggered();
    void drawRectActionTriggered();
};
#endif // MAINWINDOW_H

line.cpp

#include "line.h"
Line::Line()
{

}
void Line::paint(QPainter &painter)
{
    painter.drawLine(start,end);
}//重寫的paint函數(shù)

rect.cpp

#include "rect.h"
Rect::Rect()
{

}
void Rect::paint(QPainter &painter)
{
    painter.drawRect(start.x(),start.y(),end.x()-start.x(),end.y()-start.y());
}

shape.cpp

#include "shape.h"
Shape::Shape()
{

}

paintwidget.cpp

#include "paintwidget.h"

PaintWidget::PaintWidget(QWidget *parent)
    :QWidget(parent),currShapeCode(Shape::Line),shape(NULL),perm(false)
{
    setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);
}
void PaintWidget::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);
    painter.setBrush(Qt::white);
    painter.drawRect(0,0,size().width(),size().height());
    foreach(Shape * shape,shapeList)
    {
        shape->paint(painter);
    }
    if(shape)
    {
        shape->paint(painter);
    }
}

void PaintWidget::mousePressEvent(QMouseEvent *event)
{
    switch(currShapeCode)
    {
    case Shape::Line:
        {
            shape=new Line;
            break;
        }
    case Shape::Rect:
        {
            shape=new Rect;
            break;
        }
    }
    if(shape!=NULL)
    {
        perm=false;
        shapeList<<shape;
        shape->setStart(event->pos());
        shape->setEnd(event->pos());
    }
}

//首先我們需要按下鼠標虫给,確定直線的第一個點昆稿,所以在 mousePressEvent 里面,
//我們讓 shape 保存下 start 點厉熟。然后在鼠標按下的狀態(tài)下移動鼠標导盅,此時,直線就會發(fā)生變化
//實際上是直線的終止點在隨著鼠標移動揍瑟,所以在 mouseMoveEvent 中我們讓 shape 保存下 end 點
//然后調(diào)用 update()函數(shù)白翻,這個函數(shù)會自動調(diào)用 paintEvent()函數(shù),顯示出我們繪制的內(nèi)容绢片。
//最后滤馍,當鼠標松開時,圖形繪制完畢底循,我們將一個標志位置為 true巢株,此時說明這個圖形繪制完畢。
void PaintWidget::mouseMoveEvent(QMouseEvent *event)
{
    if(shape &&!perm)
    {
        shape->setEnd(event->pos());
        update();
    }
}

void PaintWidget::mouseReleaseEvent(QMouseEvent *event)
{
    perm=true;
}

mainwindow.cpp

#include "mainwindow.h"



MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    QToolBar *bar=this->addToolBar("Tools");//將工具欄添加
    QActionGroup *group=new QActionGroup(bar);
    QAction *drawLineAction=new QAction("Line",bar);
    drawLineAction->setToolTip(tr("Draw a line"));
    drawLineAction->setStatusTip(tr("Draw a line"));
    drawLineAction->setCheckable(true);
    drawLineAction->setChecked(true);
    group->addAction(drawLineAction);
    bar->addAction(drawLineAction);
    QAction *drawRectAction=new QAction("Rectangle",bar);
    drawRectAction->setToolTip(tr("Draw a rectangle"));
    drawRectAction->setStatusTip(tr("Draw a rectagle"));
    drawRectAction->setCheckable(true);
    group->addAction(drawRectAction);
    bar->addAction(drawRectAction);

    QLabel *statusMsg=new QLabel;
    statusBar()->addWidget(statusMsg);
    PaintWidget *paintWidget= new PaintWidget(this);
    setCentralWidget(paintWidget);
    connect(drawLineAction,SIGNAL(triggered()),this,SLOT(drawLineActionTriggered()));
    connect(drawRectAction,SIGNAL(triggered()),this,SLOT(drawRectActionTriggered()));
    connect(this,SIGNAL(changeCurrentShape(Shape::Code)),paintWidget,SLOT(setCurrentShape(Shape::Code)));


}
void MainWindow::drawLineActionTriggered()
{
    emit changeCurrentShape(Shape::Line);
}
void MainWindow::drawRectActionTriggered()
{
    emit changeCurrentShape(Shape::Rect);
}

main.cpp

#include "mainwindow.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    return a.exec();
}

image.png

從圖中可見熙涤,GraphicsView提供居中顯示阁苞。
main.cpp

#include "mainwindow.h"

#include <QApplication>
#include <QtGui>
#include<QGraphicsScene>
#include<QGraphicsView>
class DrawApp : public QWidget{
    public:
        DrawApp();
    protected:
        void paintEvent(QPaintEvent *event);
};
DrawApp::DrawApp()
{

}
void DrawApp::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);
    painter.drawLine(10,10,150,300);
}
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QGraphicsScene *scene =new QGraphicsScene;
    scene->addLine(10,10,150,300);
    QGraphicsView *view=new QGraphicsView(scene);
    view->resize(500,500);
    view->setWindowTitle("Graphics View");
    view->show();

    DrawApp *da=new DrawApp;
    da->resize(500,500);
    da->setWindowTitle("QWidget");
    da->show();
    return a.exec();
}

QPainterDevice

QPixmap:顯示圖像困檩,其中QBitmap是它一個黑白圖的子類(用isQBitmap()判斷)∧遣郏可以使用QPainter在上面繪圖悼沿。可以接受圖片路徑顯示骚灸,并用drawPixmap()函數(shù)把文件繪制到組件上糟趾。除此之外還有g(shù)rabWidget、grabWindow()函數(shù)等甚牲,將圖像繪制到目標上义郑。QPixmap不必使用指針、無法提供像素級操作丈钙,顯示一致
QImage:像素級的圖像訪問
QPicture:記錄和重現(xiàn)QPainter的命令非驮。使用方法

//記錄
QPicture picture; 
QPainter painter; 
painter.begin(&picture);              // paint in picture 
painter.drawEllipse(10,20, 80,70); // draw an ellipse 
painter.end();                           // painting done 
picture.save("drawing.pic");         // save picture

//重現(xiàn)
QPicture picture; 
picture.load("drawing.pic");          // load picture 
QPainter painter; 
painter.begin(&myImage);            // paint in myImage 
painter.drawPicture(0, 0, picture); // draw the picture at (0,0) 
painter.end(); 
旋轉(zhuǎn)

視口與窗口是一致的
世界坐標系通過改變坐標系進行放縮。

QPainter漸變
image.png

重點是:漸變對象要傳到QBrush里著恩。如果想畫漸變線段,可以把QBrush作為參數(shù)傳進QPen里蜻展。
漸變線段

void PaintedWidget::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing,true);
    QLinearGradient linearGradient(60,50,200,200);
    linearGradient.setColorAt(0.2,Qt::white);
    linearGradient.setColorAt(0.6,Qt::green);
    linearGradient.setColorAt(1.0,Qt::black);
    painter.setPen(QPen(QBrush(linearGradient),5));
    painter.drawLine(50,50,200,200);
}

漸變圖形


void PaintedWidget::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing,true);
    QLinearGradient linearGradient(60,50,200,200);
    linearGradient.setColorAt(0.2,Qt::white);
    linearGradient.setColorAt(0.6,Qt::green);
    linearGradient.setColorAt(1.0,Qt::black);
    painter.setBrush(QBrush(linearGradient));
    //漸變對象傳進QBrush里
    painter.drawEllipse(50,50,200,150);
}
QPainter

QPainter:執(zhí)行繪制操作
QPaintEngine:繪制操作與抽象二維空間的接口
QPaintDevice:二維空間的抽象
this指針是成員函數(shù)的隱含參數(shù)喉誊,在成員函數(shù)內(nèi)部指向調(diào)用對象。當我們調(diào)用成員函數(shù)時纵顾,實際上是替某個對象調(diào)用它伍茄。成員函數(shù)通過一個名為 this 的額外隱式參數(shù)來訪問調(diào)用它的那個對象,當我們調(diào)用一個成員函數(shù)時施逾,用請求該函數(shù)的對象地址初始化 this敷矫。例如,如果調(diào)用 total.isbn()則編譯器負責把 total 的地址傳遞給 isbn 的隱式形參 this汉额。
pen是線框曹仗,brush是填充圖形
setRenderHint反走樣(打開一次后所有的代碼都是反走樣的)



main.cpp

#include "mainwindow.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    PaintedWidget w;
    w.show();
    return a.exec();
}

mainwindow.cpp

#include "mainwindow.h"
#include <QPainter>
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
}

MainWindow::~MainWindow()
{
}

PaintedWidget::PaintedWidget()
{
    resize(800,600);
    setWindowTitle(tr("Paint Demo"));
}

void PaintedWidget::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);
    painter.drawLine(80,100,650,400);
    painter.setPen(Qt::red);
    painter.drawRect(10,10,100,400);
    painter.setPen(QPen(Qt::green,5));
    painter.setBrush(Qt::blue);
    painter.drawEllipse(50,150,400,200);
}

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>


class PaintedWidget:public QWidget
{
    public:
        PaintedWidget();
    protected:
        void paintEvent(QPaintEvent *event);
};

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
};
#endif // MAINWINDOW_H

自定義事件

事件與信號槽相比,可以是同步的蠕搜、又可以是異步怎茫,而函數(shù)調(diào)用(槽的回調(diào))總是同步的。同時時間可以使用過濾器妓灌。
事件type要大于999(之前的都是保留)轨蛤,介于1000~65535間。

//自定義事件的注冊
static int QEvent::registerEventType ( int hint = -1 );

Qt 自定義事件_w3cschool

filter

watched:被監(jiān)測的對象虫埂。函數(shù)調(diào)用->事件過濾->組件處理祥山。重寫時,如果需要過濾某事件需返回true掉伏。delete了某個接收組件缝呕,需將返回值設為true澳窑。
eventFilter()函數(shù)建立事件過濾器,installEventFilter()函數(shù)安裝過濾器岳颇。
事件過濾器和被安裝的組件需要在同一線程照捡。
QT事件處理分層五個層次:重定義事件處理函數(shù),重定義event()函數(shù)话侧,為單個組件安裝事件過濾器栗精,為QApplication安裝事件過濾器,重定義QCoreApplication的notify()函數(shù)瞻鹏”ⅲ控制權(quán)逐層增大

event demo
image.png

accept:事件處理函數(shù)接收了該事件,不需要再傳遞新博。
ignore:事件處理函數(shù)忽略了該事件薪夕,需要再傳遞。
isAccepted:查詢事件是不是已經(jīng)被接收了
不常用赫悄,而用響應函數(shù)代替原献。因為子類直接忽略事件,則Qt不會再去尋找其他的接收者埂淮,那么父類操作也就不能進行姑隅。
窗口關(guān)閉時要用。

#include "mainwindow.h"

#include <QApplication>
#include<QWidget>
#include<QLabel>
#include<QMouseEvent>

class EventLabel :public QLabel
{
    protected:
        void mouseMoveEvent(QMouseEvent *event);
        void mousePressEvent(QMouseEvent *event);
        void mouseReleaseEvent(QMouseEvent *event);
};
void EventLabel::mouseMoveEvent(QMouseEvent *event)
{
    this->setText(QString("<center><h1>Move:(%1,%2)</h1></center>").arg(QString::number(event->x()),QString::number(event->y())));
}
void EventLabel::mousePressEvent(QMouseEvent *event)
{
    this->setText(QString("<center><h1>Press:(%1,%2)</h1></center>").arg(QString::number(event->x()),QString::number(event->y())));
}
void EventLabel::mouseReleaseEvent(QMouseEvent *event)
{
    QString msg;
    msg.sprintf("<center><h1>Release:(%d,%d)</h1></center>",event->x(),event->y());
    this->setText(msg);
}

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    EventLabel *label=new EventLabel;
    label->setWindowTitle("MouseEvent Demo");
    label->resize(300,200);
    label->show();
    MainWindow w;
    return app.exec();
}

signal與event區(qū)別

signal有具體對象發(fā)出倔撞,然后立即交給connect函數(shù)連接的slot進行處理讲仰。事件則是追加到事件隊列尾部逐個維護(也可以插隊、篩選)痪蝇。
組件關(guān)注信號槽鄙陡,自定義組件關(guān)注事件。
protected virtual :protected可以使被修飾的方法或字段只能在當前類及其子類中使用躏啰,防止外部的無意更改趁矾。virtual是虛方法,可以由設計人員自行決定是否包含方法的實現(xiàn)给僵。
private:不能被外部訪問也不能被繼承愈魏。也會被編譯出現(xiàn)在內(nèi)存中,但編譯器限制程序不能訪問private成員
public:可以被外部訪問也可以被繼承想际。在編譯時直接編譯
protected:不能被外部訪問但可以被繼承
子類可以對父類的函數(shù)重寫培漏,或在其基礎(chǔ)上增加功能。父類的指針可以指向子類對象胡本,編譯時是從父類到子類牌柄。
構(gòu)造和析構(gòu)順序相反(構(gòu)造先父后子,析構(gòu)先子后父)
virtual:當一個成員函數(shù)需要子類重寫侧甫,則在父類應該將其聲明為virtual珊佣。即將被重寫的函數(shù)加virtual是良好的編寫習慣蹋宦。加了virtual就只能調(diào)用重寫的函數(shù)了。
父類有多個構(gòu)造函數(shù)時可以顯式調(diào)用其中一個(通過指定參數(shù))咒锻。
類的大小與成員變量有關(guān)冷冗,與成員函數(shù)無關(guān)(被聲明virtual時大小會有些微編譯器決定的變化)。
基類的析構(gòu)函數(shù)要加virtual(不加的時候惑艇,基類指針指向派生類delete時蒿辙,派生類部分清楚導致內(nèi)存泄漏,加上時滨巴,調(diào)用基類的析構(gòu)函數(shù)編譯器會從虛函數(shù)表找到要執(zhí)行的正確的函數(shù)地址思灌,即子類的析構(gòu)函數(shù)),構(gòu)造函數(shù)不能加恭取。
盡量不要多對一地多重繼承泰偿,成員名重復時會報錯。
類的繼承參考:(21條消息)
【C++】類的繼承(protected蜈垮,virtual)_protected virtual_mjiansun的博客-CSDN博客

event()

將事件對象按類型分發(fā)的函數(shù)耗跛,可以重寫該函數(shù)讓事件分發(fā)前做一些操作、或完成對自定義事件的分發(fā)攒发。類型判斷:event->type()调塌,返回QEvent::Type的類型枚舉。
evnet()返回bool類型晨继,其中true為傳入事件已識別且處理烟阐,QApplication會繼續(xù)處理事件隊列下一事件搬俊。若為false則QApplicaion轉(zhuǎn)去尋找下一個該event的處理函數(shù)紊扬。

QInputDialog

QLineEdit是參數(shù)mode,取值范圍:QLineEdit::EchoMode唉擂,默認是Normal,如果為password則是密碼輸入餐屎。
&isOK:判斷用戶按下的是OK還是Cancel
第七個參數(shù):flags指定對話框的樣式。
返回QString玩祟,通過Ok參數(shù)判斷是不是true腹缩。

    bool isOK;
    QString text=QInputDialog::getText(NULL,"TITLE","Label",QLineEdit::Normal,"your comment",&isOK);
    if(isOK)
    {
        QMessageBox::information(NULL,"Information","your comment is:<b>"+text+"</b>",QMessageBox::Yes||QMessageBox::No,QMessageBox::Yes);
    }
QMessageBox

1.QMessageBox一種是static(返回StandardButton,通過返回值判斷)一種是構(gòu)造函數(shù)(通過if判斷)空扎。
構(gòu)造函數(shù):

    //msgbox 構(gòu)造函數(shù)方式
    QMessageBox message(QMessageBox::NoIcon,"Show Qt","Do you want to show qt dialog?",QMessageBox::Yes|QMessageBox::No,NULL);
    if(message.exec()==QMessageBox::Yes)
    {
        QMessageBox::aboutQt(NULL,"About Qt");
    }

static:

    //msgbox static方式返回值
    QMessageBox::StandardButton rb=QMessageBox::question(NULL,"Show QT","Do you want to show Qt dialog?",QMessageBox::Yes|QMessageBox::No,QMessageBox::Yes);
    if(rb==QMessageBox::Yes)
    {
        QMessageBox::aboutQt(NULL,"About Qt");
    }

2.Yes和No按鈕:QMessageBox::Yes | QMessageBox::No藏鹊。msgbox static分類:critical(紅色禁止),warning(黃色警告)转锈,question(問好)盘寡,about(沒有選擇按鈕只有Ok)。
3.msg對話框文本支持:支持HTML標簽撮慨。
4.定義圖片:非靜態(tài)竿痰,用exec()而不是show()
5.png格式脆粥,相對路徑。

QMessageBox message(QMessageBox::NoIcon, "Title", "Content with icon."); 
message.setIconPixmap(QPixmap("icon.png")); 
message.exec();
parent參數(shù)

作用:用于指示是否是頂層容器(有parent的就不是頂層容器)影涉。指明組件的父組件变隔,這樣在父組件delete時所有的子也會被回收。

QColorDialog

1%%2是占位符蟹倾,arg()替換掉占位符匣缘,QSttring::number()把值替換成等值字符串。這里是把RGB值列出來并輸出喊式。

void MainWindow::open()
{
    QString path=QFileDialog::getOpenFileName(this,tr("Open the file"),".",tr("Image Files(*.jpg*.png)"));
    if(path.length()==0)
    {
        QMessageBox::information(NULL,tr("Path"),tr("You didn;t select any files."));
    }
    else
    {
        QMessageBox::information(NULL,tr("Path"),tr("You selected")+path);
    }
//    QMessageBox::information(NULL,tr("Open"),tr("Open a file"));
    QColor color=QColorDialog::getColor(Qt::white,this);
    QString msg=QString("r:%1,g:%2,b").arg(QString::number(color.red()),QString::number(color.green()),QString::number(color.blue()));
    QMessageBox::information(NULL,"Selected color",msg);
}
QFileDialog與getOpenFileName

getOpenFileName函數(shù)簽名:parent父組件孵户、caption對話框標題、dir默認打開的目錄岔留、filter對話框的后綴名過濾器夏哭,如需要多個可使用;献联;分割竖配、selectedFilter默認選擇的過濾器、options對話框參數(shù)設定里逆,取值為enumQFileDialog::Option进胯,可用|運算組合。
getOpenFileNames()選擇多個文件原押,返回QStringList
另一種寫法胁镐。getOpenFileNmae是本地對話框,QFileDialog是Qt自己繪制的

QFileDialog *fileDialog = new QFileDialog(this); 
        fileDialog->setWindowTitle(tr("Open Image")); 
        fileDialog->setDirectory("."); 
        fileDialog->setFilter(tr("Image Files(*.jpg *.png)")); 
        if(fileDialog->exec() == QDialog::Accepted) { 
                QString path = fileDialog->selectedFiles()[0]; 
                QMessageBox::information(NULL, tr("Path"), tr("You selected ") + path); 
        } else { 
                QMessageBox::information(NULL, tr("Path"), tr("You didn't select any files.")); 
        }

mainwindow.cpp诸衔,添加了文件打開框的實際操作

#include "mainwindow.h"
#include<QAction>
#include<QMenu>
#include<QMenuBar>
#include<QKeySequence>
#include<QToolBar>
#include<QMessageBox>
#include<QLabel>
#include<QStatusBar>
#include<QFileDialog>
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    //定義QAction 創(chuàng)造一個對象
    openAction=new QAction(tr("&Open"),this);
    openAction->setShortcut(QKeySequence::Open);//用于實現(xiàn)跨平臺快捷鍵
    openAction->setStatusTip(tr("Open a file."));//狀態(tài)欄的提示
    openAction->setIcon(QIcon(":/Open.png"));
    //把QAction添加到菜單和工具條
    connect(openAction,SIGNAL(triggered()),this,SLOT(open()));

    QMenu *file=menuBar()->addMenu(tr("&File"));
    file->addAction(openAction);

    QToolBar *toolBar=addToolBar(tr("&File"));
    toolBar->addAction(openAction);

    msgLabel=new QLabel;
    msgLabel->setMinimumSize(msgLabel->sizeHint());//設置大小為本身建議的大小
    msgLabel->setAlignment(Qt::AlignHCenter);//設置顯示規(guī)則水平居中
    statusBar()->addWidget(msgLabel);//把label添加到狀態(tài)欄
    statusBar()->setStyleSheet(QString("QStatusBar::item{border:0px}"));
}

void MainWindow::open()
{
    QString path=QFileDialog::getOpenFileName(this,tr("Open the file"),".",tr("Image Files(*.jpg*.png)"));
    if(path.length()==0)
    {
        QMessageBox::information(NULL,tr("Path"),tr("You didn;t select any files."));
    }
    else
    {
        QMessageBox::information(NULL,tr("Path"),tr("You selected")+path);
    }
//    QMessageBox::information(NULL,tr("Open"),tr("Open a file"));

}
MainWindow::~MainWindow()
{
    }



狀態(tài)欄

信息類型:臨時信息(提示)盯漂,一般信息(頁碼),永久信息(不會消失的信息笨农,如按鍵狀態(tài))
demo3
mainwindow.cpp

#include "mainwindow.h"
#include<QAction>
#include<QMenu>
#include<QMenuBar>
#include<QKeySequence>
#include<QToolBar>
#include<QMessageBox>
#include<QLabel>
#include<QStatusBar>
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    //定義QAction 創(chuàng)造一個對象
    openAction=new QAction(tr("&Open"),this);
    openAction->setShortcut(QKeySequence::Open);//用于實現(xiàn)跨平臺快捷鍵
    openAction->setStatusTip(tr("Open a file."));//狀態(tài)欄的提示
    openAction->setIcon(QIcon(":/Open.png"));
    //把QAction添加到菜單和工具條
    connect(openAction,SIGNAL(triggered()),this,SLOT(open()));

    QMenu *file=menuBar()->addMenu(tr("&File"));
    file->addAction(openAction);

    QToolBar *toolBar=addToolBar(tr("&File"));
    toolBar->addAction(openAction);

    msgLabel=new QLabel;
    msgLabel->setMinimumSize(msgLabel->sizeHint());//設置大小為本身建議的大小
    msgLabel->setAlignment(Qt::AlignHCenter);//設置顯示規(guī)則水平居中
    statusBar()->addWidget(msgLabel);//把label添加到狀態(tài)欄
    statusBar()->setStyleSheet(QString("QStatusBar::item{border:0px}"));
}

void MainWindow::open()
{
    QMessageBox::information(NULL,tr("Open"),tr("Open a file"));

}
MainWindow::~MainWindow()
{
    }

main.cpp

#include "mainwindow.h"
#include <QApplication>


int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    return a.exec();
}

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

class QAction;//前向聲明
class QLabel;
class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
private slots:
    void open();
private:
        QAction *openAction;
        QLabel *msgLabel;
};
#endif // MAINWINDOW_H

QAction就缆、工具欄和菜單的demo 添加圖標等demo2:

https://www.w3cschool.cn/learnroadqt/7yl81j4f.html

圖片.png

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

class QAction;//前向聲明

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
private slots:
    void open();
private:
        QAction *openAction;
};
#endif // MAINWINDOW_H

main.cpp

#include "mainwindow.h"
#include <QApplication>


int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    return a.exec();
}

mainwindow.cpp

#include "mainwindow.h"
#include<QAction>
#include<QMenu>
#include<QMenuBar>
#include<QKeySequence>
#include<QToolBar>
#include<QMessageBox>
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    //定義QAction 創(chuàng)造一個對象
    openAction=new QAction(tr("&Open"),this);
    openAction->setShortcut(QKeySequence::Open);//用于實現(xiàn)跨平臺快捷鍵
    openAction->setStatusTip(tr("Open a file."));//狀態(tài)欄的提示
    openAction->setIcon(QIcon(":/Open.png"));
    //把QAction添加到菜單和工具條
    connect(openAction,SIGNAL(triggered()),this,SLOT(open()));

    QMenu *file=menuBar()->addMenu(tr("&File"));
    file->addAction(openAction);

    QToolBar *toolBar=addToolBar(tr("&File"));
    toolBar->addAction(openAction);
}

void MainWindow::open()
{
    QMessageBox::information(NULL,tr("Open"),tr("Open a file"));

}
MainWindow::~MainWindow()
{
    }



QAction、工具欄和菜單的demo

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

class QAction;//前向聲明

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
private:
        QAction *openAction;
};
#endif // MAINWINDOW_H

main.cpp

#include "mainwindow.h"
#include <QApplication>


int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    return a.exec();
}

mainwindow.cpp

#include "mainwindow.h"
#include<QAction>
#include<QMenu>
#include<QMenuBar>
#include<QKeySequence>
#include<QToolBar>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    //定義QAction 創(chuàng)造一個對象
    openAction=new QAction(tr("&Open"),this);
    openAction->setShortcut(QKeySequence::Open);//用于實現(xiàn)跨平臺快捷鍵
    openAction->setStatusTip(tr("Open a file."));//狀態(tài)欄的提示

    //把QAction添加到菜單和工具條
    QMenu 谒亦。菜單是上面的竭宰,工具欄是下面的
*file=menuBar()->addMenu(tr("&File"));
    file->addAction(openAction);

    QToolBar *toolBar=addToolBar(tr("&File"));
    toolBar->addAction(openAction);
}

MainWindow::~MainWindow()
{
}


Action類

保存action的信息,如文本描述份招、圖標切揭、快捷鍵、信號槽

Meta-Object 系統(tǒng)

內(nèi)仕ぁ(反射):程序在運行時獲取類的相關(guān)信息廓旬,如方法屬性信號列表槽列表,這些基本信息就是meta-information鄙漏。

信號槽進階

函數(shù)簽名:定義函數(shù)的輸入輸出嗤谚。包含參數(shù)及其類型棺蛛,返回值及其類型,可能拋出傳回的異常巩步,可用性信息(public\static\prototype)
一個槽可以連接多個信號(任一信號觸發(fā)旁赊,執(zhí)行slot),一個信號可以連接多個槽(槽會接連調(diào)用椅野,但調(diào)用順序不定终畅,類似verilog),一個信號可以連接一個信號竟闪,槽可以被取消鏈接(disconnect)离福。
信號和槽的參數(shù)個數(shù)類型順序必須一致,多的就會被忽略掉炼蛤。
通過if防止循環(huán)連接
一個典型的類及其使用:

class Employee:public QObject
{
    Q_OBJECT
public:
    Employee() {mySalary=0;}
    int salary() const{return mySalary;}
//const在Public函數(shù)中常用妖爷,表明該函數(shù)不能修改類中的成員變量
public slots:
    void setSalary(int newSalary);
signals:
    void salaryChanged(int newSalary);
private:
    int mySalary;
};

void Employee::setSalary(int newSalary) 
{ 
        if (newSalary != mySalary) { 
                mySalary = newSalary; 
                emit salaryChanged(mySalary); 
        } 
}
week1:

配了環(huán)境,qtcreator下cmake的配置仍未解決理朋,無法使用VS絮识,但是原生編輯器能跑。學了layout\信號槽\幾個常用組件嗽上,用fiddler修改下載源次舌。
ifndef:https://blog.csdn.net/SummerXRT/article/details/119741741
頭文件:C 頭文件 | 菜鳥教程 (runoob.com)
構(gòu)造和析構(gòu):C++構(gòu)造函數(shù)和析構(gòu)函數(shù)詳解 - 知乎 (zhihu.com)

image.png

示例:
main.cpp

#include<QApplication>
#include"finddialog.h"

int main(int argc,char *argv[])
{
    QApplication app(argc,argv);
    FindDialog *dialog = new FindDialog;
    dialog->show();
    return app.exec();
}

FindDialog.cpp
::和:https://blog.csdn.net/qingkongyeyue/article/details/52948266

#include <QtGui>
#include "finddialog.h"

FindDialog::FindDialog(QWidget *parent)
    :QDialog(parent)
{
    label = new QLabel(tr("Find &what:"));
    lineEdit = new QLineEdit;
    label->setBuddy(lineEdit);

    caseCheckBox = new QCheckBox(tr("Match &case"));
    backwardCheckBox = new QCheckBox(tr("Search &backford"));

    findButton = new QPushButton(tr("&Find"));
    findButton->setDefault(true);
    findButton->setEnabled(false);

    closeButton = new QPushButton(tr("Close"));

    connect(lineEdit,SIGNAL(textChanged(const QString&)),this,SLOT(enableFindButton(const QString&)));
    connect(findButton,SIGNAL(clicked()),this,SLOT(findClicked()));
    connect(closeButton,SIGNAL(clicked()),this,SLOT(close()));

    QHBoxLayout *topLeftLayout = new QHBoxLayout;
    topLeftLayout->addWidget(label);
    topLeftLayout->addWidget(lineEdit);

    QVBoxLayout *leftLayout=new QVBoxLayout;
    leftLayout->addLayout(topLeftLayout);
    leftLayout->addWidget(caseCheckBox);
    leftLayout->addWidget(backwardCheckBox);

    QVBoxLayout *rightLayout=new QVBoxLayout;
    rightLayout->addWidget(findButton);
    rightLayout->addWidget(closeButton);
    rightLayout->addStretch();

    QHBoxLayout *mainLayout=new QHBoxLayout;
    mainLayout->addLayout(leftLayout);
    mainLayout->addLayout(rightLayout);
    setLayout(mainLayout);

    setWindowTitle(tr("Find"));
    setFixedHeight(sizeHint().height());
}
FindDialog::~FindDialog()
{

}
void FindDialog::findClicked()
{
    QString text = lineEdit->text();
    Qt::CaseSensitivity cs=caseCheckBox->isChecked()?Qt::CaseInsensitive : Qt::CaseSensitive;
    if(backwardCheckBox->isChecked())
    {
        emit findPrevious(text,cs);
    }else
    {
        emit findNext(text,cs);
    }
}
void FindDialog::enableFindButton(const QString &text)
{
    findButton->setEnabled(!text.isEmpty());
}

.h文件:

#ifndef FINDDIALOG_H
#define FINDDIALOG_H

#include<QDialog>
#include<QLabel>
#include<QLineEdit>
#include<QCheckBox>
#include<QApplication>
#include<QHBoxLayout>
#include<QVBoxLayout>
#include<QPushButton>

class QCheckBox;
class QLabel;
class QLineEdit;
class QPushButton;


class FindDialog : public QDialog
{
    Q_OBJECT

public:
    FindDialog(QWidget *parent = 0);
    ~FindDialog();
signals:
    void findNext(const QString &str,Qt::CaseSensitivity cs);
    void findPrevious(const QString &str,Qt::CaseSensitivity cs);
private slots:
    void findClicked();
    void enableFindButton(const QString &text);
private:
    QLabel *label;
    QLineEdit *lineEdit;
    QCheckBox *caseCheckBox;
    QCheckBox *backwardCheckBox;
    QPushButton *findButton;
    QPushButton *closeButton;
};
#endif // FINDDIALOG_H

參考資料

qt鏡像站:https://mirrors.tuna.tsinghua.edu.cn/qt/archive/qt/
組件更新:
https://blog.csdn.net/SHIE_Ww/article/details/124074573
教程:https://www.w3cschool.cn/learnroadqt/c84q1j3t.html
qt串口通信:https://shenmingyi.blog.csdn.net/article/details/81669540?spm=1001.2101.3001.6650.5&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-5-81669540-blog-123432413.235%5Ev28%5Epc_relevant_t0_download&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-5-81669540-blog-123432413.235%5Ev28%5Epc_relevant_t0_download

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市兽愤,隨后出現(xiàn)的幾起案子彼念,更是在濱河造成了極大的恐慌,老刑警劉巖浅萧,帶你破解...
    沈念sama閱讀 206,839評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件逐沙,死亡現(xiàn)場離奇詭異,居然都是意外死亡惯殊,警方通過查閱死者的電腦和手機酱吝,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評論 2 382
  • 文/潘曉璐 我一進店門也殖,熙熙樓的掌柜王于貴愁眉苦臉地迎上來土思,“玉大人,你說我怎么就攤上這事忆嗜〖喝澹” “怎么了?”我有些...
    開封第一講書人閱讀 153,116評論 0 344
  • 文/不壞的土叔 我叫張陵捆毫,是天一觀的道長闪湾。 經(jīng)常有香客問我,道長绩卤,這世上最難降的妖魔是什么途样? 我笑而不...
    開封第一講書人閱讀 55,371評論 1 279
  • 正文 為了忘掉前任江醇,我火速辦了婚禮,結(jié)果婚禮上何暇,老公的妹妹穿的比我還像新娘陶夜。我一直安慰自己,他們只是感情好裆站,可當我...
    茶點故事閱讀 64,384評論 5 374
  • 文/花漫 我一把揭開白布条辟。 她就那樣靜靜地躺著,像睡著了一般宏胯。 火紅的嫁衣襯著肌膚如雪羽嫡。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,111評論 1 285
  • 那天肩袍,我揣著相機與錄音杭棵,去河邊找鬼。 笑死氛赐,一個胖子當著我的面吹牛颜屠,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播鹰祸,決...
    沈念sama閱讀 38,416評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼甫窟,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了蛙婴?” 一聲冷哼從身側(cè)響起粗井,我...
    開封第一講書人閱讀 37,053評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎街图,沒想到半個月后浇衬,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,558評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡餐济,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,007評論 2 325
  • 正文 我和宋清朗相戀三年耘擂,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片絮姆。...
    茶點故事閱讀 38,117評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡醉冤,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出篙悯,到底是詐尸還是另有隱情蚁阳,我是刑警寧澤,帶...
    沈念sama閱讀 33,756評論 4 324
  • 正文 年R本政府宣布鸽照,位于F島的核電站螺捐,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜定血,卻給世界環(huán)境...
    茶點故事閱讀 39,324評論 3 307
  • 文/蒙蒙 一赔癌、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧澜沟,春花似錦届榄、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至席噩,卻和暖如春班缰,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背悼枢。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評論 1 262
  • 我被黑心中介騙來泰國打工埠忘, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人馒索。 一個月前我還...
    沈念sama閱讀 45,578評論 2 355
  • 正文 我出身青樓莹妒,卻偏偏與公主長得像,于是被迫代替她去往敵國和親绰上。 傳聞我的和親對象是個殘疾皇子旨怠,可洞房花燭夜當晚...
    茶點故事閱讀 42,877評論 2 345

推薦閱讀更多精彩內(nèi)容