Resive world

Come world to Record life


  • Home

  • Tags

  • Categories

  • Archives

  • Sitemap

  • Search

利用BigDump向mysql导入超大数据

Posted on 2015-11-05 | In Database

本来就只想轻轻松松把服务器的mysql数据导入到本地的mysql里的,结果发现这个问题还是一个坑。phpmyadmin里把导入数据的大小限定为了2M,然而我的数据有4M。想分表导入结果发现有一个表的大小还是超过了传输上限。百度了以下据说可以通过修改php和phpmyadmin的配置文件来略微的扩容,结果配置了半天头都大了而且还没有用,后来据说可以通过配置主从服务器来传输,但是那个从服务器的配置始终弄不对(其实是对这种设置的用途理解不够)。最后终于还是用了第三方的脚本,这也是无奈之举,不过用了才知道还是很方便的。

BigDump.php脚本源码在官网下载Bigdump。(其实只有1000多行,本来打算直接贴过来的,但是发现这里的文本编辑器会对一些字符进行转义,导致保存下来的文件不正确,后来有一次用的时候才发现问题,于是直接贴一下官网地址,也方便以后查询更新。)

使用之前需要稍微进行一下配置(这是显然的,要不然怎么知道写到哪个数据库里),在文件中的40行左右找到以下几项:

1
2
3
4
$db_server   = '';
$db_name = '';
$db_username = '';
$db_password = '';

分别填入ip(本机的当然写localhost),数据库的库名,登陆的用户名,密码。

这样就算配置完成了,接下来只要把这个文件放在站点的某个位置里(为了能通过浏览器访问到),再把需要导入的.sql文件放在同文件夹下即可,通过浏览器访问这个文件,找到需要导入的数据库,点击根据提示操作就行了。

php5-mysql-phpmyadmin安装和配置

Posted on 2015-11-04 | In Database

php5和mysql的安装比较无脑,也基本无需配置,安装命令:

1
myths@myths-X450LD:~$ sudo apt-get install php5
1
myths@myths-X450LD:~$ sudo apt-get install mysql-server

唯一要注意的是mysql安装的时候需要输入密码,这就是数据库的密码,以后要用到的,需要记住。

接下来安装phpmyadmin,外行乍一看觉得这是个管理php的东西,其实php要个啥子管理啊,这个是用php写的用来管理mysql的小软件,通过这个可以方便的管理数据库。

安装命令:myths@myths-X450LD:~$ sudo apt-get install phpmyadmin

当然安装中会提示输一些东西,就是一种图形界面的配置,方便人用的。这当中需要输入之前安装mysql时的密码,照着弄就对了。

安装结束后,phpmyadmin被默认安装到了/usr/share/phpmyadmin中,软件的入口当然就是index.php了。不过为了访问的方便,还是加一个链接到我们的目录中:
myths@myths-X450LD:sudo ln -s /usr/share/phpmyadmin /var/www/html/
这样就可以通过本地访问该网页的形式打开这个小软件了。

apache2服务器的搭建与配置

Posted on 2015-11-04 | In Apache

搭建apache2其实并不难,只是网上的资料有很多都过时了,之前被误导过好几次,走了很多弯路。趁着这次在本地搭建网站的时机重新捋一下思路,也方便以后有需求的时候查阅。

首先当然是下载包包:

1
myths@myths-X450LD:~$ sudo apt-get install apache2

装完后就可以用了,在地址栏输入本地回送地址127.0.0.1或者localhost就可以进入到默认的界面了。

默认的界面当然就是apache2的说明界面了。其实很多情况下并不需要在网上寻找帮助文档,几乎所有的软件都会自带使用说明,只是略长,我们一般都懒得看。但是其实很多重要的东西就在这当中,比如apache2的默认界面里:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
Ubuntu Logo Apache2 Ubuntu Default Page
It works!
This is the default welcome page used to test the correct operation of the Apache2 server after installation on Ubuntu systems. It is based on the equivalent page on Debian, from which the Ubuntu Apache packaging is derived. If you can read this page, it means that the Apache HTTP server installed at this site is working properly. You should replace this file (located at /var/www/html/index.html) before continuing to operate your HTTP server.
If you are a normal user of this web site and don't know what this page is about, this probably means that the site is currently unavailable due to maintenance. If the problem persists, please contact the site's administrator.
Configuration Overview
Ubuntu's Apache2 default configuration is different from the upstream default configuration, and split into several files optimized for interaction with Ubuntu tools. The configuration system is fully documented in /usr/share/doc/apache2/README.Debian.gz. Refer to this for the full documentation. Documentation for the web server itself can be found by accessing the manual if the apache2-doc package was installed on this server.
The configuration layout for an Apache2 web server installation on Ubuntu systems is as follows:
/etc/apache2/
|-- apache2.conf
| `-- ports.conf
|-- mods-enabled
| |-- *.load
| `-- *.conf
|-- conf-enabled
| `-- *.conf
|-- sites-enabled
| `-- *.conf

apache2.conf is the main configuration file. It puts the pieces together by including all remaining configuration files when starting up the web server.
ports.conf is always included from the main configuration file. It is used to determine the listening ports for incoming connections, and this file can be customized anytime.
Configuration files in the mods-enabled/, conf-enabled/ and sites-enabled/ directories contain particular configuration snippets which manage modules, global configuration fragments, or virtual host configurations, respectively.
They are activated by symlinking available configuration files from their respective *-available/ counterparts. These should be managed by using our helpers a2enmod, a2dismod, a2ensite, a2dissite, and a2enconf, a2disconf . See their respective man pages for detailed information.
The binary is called apache2\. Due to the use of environment variables, in the default configuration, apache2 needs to be started/stopped with /etc/init.d/apache2 or apache2ctl. Calling /usr/bin/apache2 directly will not work with the default configuration.
Document Roots
By default, Ubuntu does not allow access through the web browser to any file apart of those located in /var/www, public_html directories (when enabled) and /usr/share (for web applications). If your site is using a web document root located elsewhere (such as in /srv) you may need to whitelist your document root directory in /etc/apache2/apache2.conf.
The default Ubuntu document root is /var/www/html. You can make your own virtual hosts under /var/www. This is different to previous releases which provides better security out of the box.
Reporting Problems
Please use the ubuntu-bug tool to report bugs in the Apache2 package with Ubuntu. However, check existing bug reports before reporting a new bug.
Please report bugs specific to modules (such as PHP and others) to respective packages, not to the web server itself.
Valid XHTML 1.0 Transitional

仅仅从这个文件中,我们就可以至少得到以下的重要信息:

  1. 当访问本机的时候,默认进入的页面是/var/www/html/index.html。
  2. 配置系统的说明在/usr/share/doc/apache2/README.Debian.gz中。
  3. 完整使用手册可以通过安装apache2-doc 进行下载。
  4. 主配置文件为/etc/apache2/apache2.conf。
  5. 启动和关闭apache2服务可以通过执行命令/etc/init.d/apache2 start(stop / restart)当然也可以是 service apache2 start (stop / restart)。这里一定要注意记得!记得!加root权限!这里不加root权限并没有明显的提示(好坑),当遇到问题的时候很难让人想到是这里出的错,所以一定要记得!记得!加root权限!
  6. 默认情况下apache2拒绝访问除/var/www 和/usr/share文件夹外的其他文件,这种权限是通过apache2.conf文件来控制的.

默认的apache2.conf为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
# This is the main Apache server configuration file.  It contains the
# configuration directives that give the server its instructions.
# See http://httpd.apache.org/docs/2.4/ for detailed information about
# the directives and /usr/share/doc/apache2/README.Debian about Debian specific
# hints.
#
#
# Summary of how the Apache 2 configuration works in Debian:
# The Apache 2 web server configuration in Debian is quite different to
# upstream's suggested way to configure the web server. This is because Debian's
# default Apache2 installation attempts to make adding and removing modules,
# virtual hosts, and extra configuration directives as flexible as possible, in
# order to make automating the changes and administering the server as easy as
# possible.

# It is split into several files forming the configuration hierarchy outlined
# below, all located in the /etc/apache2/ directory:
#
# /etc/apache2/
# |-- apache2.conf
# | `-- ports.conf
# |-- mods-enabled
# | |-- *.load
# | `-- *.conf
# |-- conf-enabled
# | `-- *.conf
# `-- sites-enabled
# `-- *.conf
#
#
# * apache2.conf is the main configuration file (this file). It puts the pieces
# together by including all remaining configuration files when starting up the
# web server.
#
# * ports.conf is always included from the main configuration file. It is
# supposed to determine listening ports for incoming connections which can be
# customized anytime.
#
# * Configuration files in the mods-enabled/, conf-enabled/ and sites-enabled/
# directories contain particular configuration snippets which manage modules,
# global configuration fragments, or virtual host configurations,
# respectively.
#
# They are activated by symlinking available configuration files from their
# respective *-available/ counterparts. These should be managed by using our
# helpers a2enmod/a2dismod, a2ensite/a2dissite and a2enconf/a2disconf. See
# their respective man pages for detailed information.
#
# * The binary is called apache2\. Due to the use of environment variables, in
# the default configuration, apache2 needs to be started/stopped with
# /etc/init.d/apache2 or apache2ctl. Calling /usr/bin/apache2 directly will not
# work with the default configuration.

# Global configuration
#

#
# ServerRoot: The top of the directory tree under which the server's
# configuration, error, and log files are kept.
#
# NOTE! If you intend to place this on an NFS (or otherwise network)
# mounted filesystem then please read the Mutex documentation (available
# at <URL:http://httpd.apache.org/docs/2.4/mod/core.html#mutex>);
# you will save yourself a lot of trouble.
#
# Do NOT add a slash at the end of the directory path.
#
#ServerRoot "/etc/apache2"

#
# The accept serialization lock file MUST BE STORED ON A LOCAL DISK.
#
Mutex file:${APACHE_LOCK_DIR} default

#
# PidFile: The file in which the server should record its process
# identification number when it starts.
# This needs to be set in /etc/apache2/envvars
#
PidFile ${APACHE_PID_FILE}

#
# Timeout: The number of seconds before receives and sends time out.
#
Timeout 300

#
# KeepAlive: Whether or not to allow persistent connections (more than
# one request per connection). Set to "Off" to deactivate.
#
KeepAlive On

#
# MaxKeepAliveRequests: The maximum number of requests to allow
# during a persistent connection. Set to 0 to allow an unlimited amount.
# We recommend you leave this number high, for maximum performance.
#
MaxKeepAliveRequests 100

#
# KeepAliveTimeout: Number of seconds to wait for the next request from the
# same client on the same connection.
#
KeepAliveTimeout 5

# These need to be set in /etc/apache2/envvars
User ${APACHE_RUN_USER}
Group ${APACHE_RUN_GROUP}

#
# HostnameLookups: Log the names of clients or just their IP addresses
# e.g., www.apache.org (on) or 204.62.129.132 (off).
# The default is off because it'd be overall better for the net if people
# had to knowingly turn this feature on, since enabling it means that
# each client request will result in AT LEAST one lookup request to the
# nameserver.
#
HostnameLookups Off

# ErrorLog: The location of the error log file.
# If you do not specify an ErrorLog directive within a <VirtualHost>
# container, error messages relating to that virtual host will be
# logged here. If you *do* define an error logfile for a <VirtualHost>
# container, that host's errors will be logged there and not here.
#
ErrorLog ${APACHE_LOG_DIR}/error.log

#
# LogLevel: Control the severity of messages logged to the error_log.
# Available values: trace8, ..., trace1, debug, info, notice, warn,
# error, crit, alert, emerg.
# It is also possible to configure the log level for particular modules, e.g.
# "LogLevel info ssl:warn"
#
LogLevel warn

# Include module configuration:
IncludeOptional mods-enabled/*.load
IncludeOptional mods-enabled/*.conf

# Include list of ports to listen on
Include ports.conf

# Sets the default security model of the Apache2 HTTPD server. It does
# not allow access to the root filesystem outside of /usr/share and /var/www.
# The former is used by web applications packaged in Debian,
# the latter may be used for local directories served by the web server. If
# your system is serving content from a sub-directory in /srv you must allow
# access here, or in any related virtual host.
<Directory />
Options FollowSymLinks
AllowOverride None
Require all denied
</Directory>

<Directory /usr/share>
AllowOverride None
Require all granted
</Directory>

<Directory /var/www/>
Options Indexes FollowSymLinks
AllowOverride None
Require all granted
</Directory>

#<Directory /srv/>
# Options Indexes FollowSymLinks
# AllowOverride None
# Require all granted
#</Directory>

# AccessFileName: The name of the file to look for in each directory
# for additional configuration directives. See also the AllowOverride
# directive.
#
AccessFileName .htaccess

#
# The following lines prevent .htaccess and .htpasswd files from being
# viewed by Web clients.
#
<FilesMatch "^.ht">
Require all denied
</FilesMatch>

#
# The following directives define some format nicknames for use with
# a CustomLog directive.
#
# These deviate from the Common Log Format definitions in that they use %O
# (the actual bytes sent including headers) instead of %b (the size of the
# requested file), because the latter makes it impossible to detect partial
# requests.
#
# Note that the use of %{X-Forwarded-For}i instead of %h is not recommended.
# Use mod_remoteip instead.
#
LogFormat "%v:%p %h %l %u %t "%r" %>s %O "%{Referer}i" "%{User-Agent}i"" vhost_combined
LogFormat "%h %l %u %t "%r" %>s %O "%{Referer}i" "%{User-Agent}i"" combined
LogFormat "%h %l %u %t "%r" %>s %O" common
LogFormat "%{Referer}i -> %U" referer
LogFormat "%{User-agent}i" agent

# Include of directories ignores editors' and dpkg's backup files,
# see README.Debian for details.

# Include generic snippets of statements
IncludeOptional conf-enabled/*.conf

# Include the virtual host configurations:
IncludeOptional sites-enabled/*.conf

# vim: syntax=apache ts=4 sw=4 sts=4 sr noet

注意这当中的一段:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<Directory />
Options FollowSymLinks
AllowOverride None
Require all denied
</Directory>

<Directory /usr/share>
AllowOverride None
Require all granted
</Directory>

<Directory /var/www/>
Options Indexes FollowSymLinks
AllowOverride None
Require all granted
</Directory>

由这段可以很容易的知道apache2到底为哪些文件夹赋予了打开的权限了。以后就可以通过修改这里达到各种不可告人的目的了。

最后还有一个重要的配置,就是默认目录的更改。默认的目录其实是记录在:/etc/apache2/sites-available/000-default.conf 文件当中(在/etc/apache2/sites-enable/中也有一个指向他的链接):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
myths@myths-X450LD:/etc/apache2/sites-available$ cat 000-default.conf 
<VirtualHost *:80>
# The ServerName directive sets the request scheme, hostname and port that
# the server uses to identify itself. This is used when creating
# redirection URLs. In the context of virtual hosts, the ServerName
# specifies what hostname must appear in the request's Host: header to
# match this virtual host. For the default virtual host (this file) this
# value is not decisive as it is used as a last resort host regardless.
# However, you must set it for any further virtual host explicitly.
#ServerName www.example.com

ServerAdmin webmaster@localhost
DocumentRoot /var/www/html

# Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
# error, crit, alert, emerg.
# It is also possible to configure the loglevel for particular
# modules, e.g.
#LogLevel info ssl:warn

ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined

# For most configuration files from conf-available/, which are
# enabled or disabled at a global level, it is possible to
# include a line for only one particular virtual host. For example the
# following line enables the CGI configuration for this host only
# after it has been globally disabled with "a2disconf".
#Include conf-available/serve-cgi-bin.conf
</VirtualHost>

# vim: syntax=apache ts=4 sw=4 sts=4 sr noet

当中的“DocumentRoot ”键对应的值就是默认的目录了,可以任由我们修改了。

apache2的简单配置基本就是这些,不需要百度,我们也是完全可以自己弄清楚的。

注:

  1. 修改完配置文件后记得重启服务
  2. 可以顺手吧/var/www的权限设置为777方便修改网页

Linux中ln命令的用法以及分析

Posted on 2015-11-03 | In Linux

在ubuntu用也有类似于windows中快捷方式这种类型的东西,即链接。这里一般使用ln命令来执行得到,ln命令用法简单,但是与windows不同,这里有硬链接和软链接两种类型的链接。在介绍两种链接的时候,我们先来了解一下Linux的文件系统。

文件系统

在Linux中每一个文件大体上由三个部分组成:

  1. 文件名:这个是用来标记这个文件的符号,也就是我们所理解的文件名;
  2. inode:inode存放的是文件的metadata,也就是元信息,包括了文件的权限、创建时间、修改时间、唯一id、文件种类、一个与文件名数目对应的链接数,最后还有一个指向实际数据区域的指针。我们可以用stat命令来查看文件的inode信息。
  3. 数据区:这里是真正保存数据的地方。

当我们创建一个文件的时候,我们实际上是创建了这个文件的文件名以及inode,只有当我们真正写数据的时候,我们才会想数据区里写入数据。
当我们删除一个文件的时候,我们实际上是删除了这个文件的文件名,然后这个文件对应的inode的连接数会减一,当这个连接数减为0的时候,操作系统才会讲这个inode删除,也就是删除了这个文件。

硬链接

硬链接相当于给文件重新起了一个名字,没有创建inode,只是对inode的链接数加了1,更没有数据的拷贝,新创建的名字与原来的名字从本质上没有任何先后次序,是对等存在的。对一个文件的修改就是对另一个文件的修改。当删除一个文件的时候,只是删除了这个文件名,并且将对应inode的链接数减了1。

硬链接还有一些非常有趣的性质:

不允许给目录创建硬链接

为什么不允许给目录创建硬链接呢?原因其实非常好玩。事实上Linux对目录本身是有硬链接的,我们知道每一个文件夹下都至少会有两个链接,一个是’.’、表示当前文件本身;另一个是’..’、表示当前文件的父目录。事实上,这个’.’就是对当前文件的一个硬链接,而’..’是对当前文件夹的父目录的硬链接,这就是为什么如果我们新建一个文件夹后,用stat查看这个文件夹的链接数,会发现这个数至少是2而不是1。
既然有硬链接,那么为什么不允许用户创建呢?原因也很有趣。如果任由用户随意添加硬链接,那么很容易出现一种情况,就是比如dir1->dir3 , dir2->dir3,这时如果我们在dir3下执行cd .. ,那么我们应该跳到哪里呢?显然这是一个不可描述的问题。因此,为了避免这种情况的发生,Linux的设计者才做了这样一个规定。

只有在同一文件系统中的文件之间才能创建链接。

这一点跟软链接不同,由于硬链接中的两个文件名需要映射到同一个inode上,而这个文件系统的inode显然不能被另一个文件系统直接看到,因此也就不能跨文件系统访问了。

事实上,硬链接用的不多,比较常用的是软链接:

软链接

软链接又叫符号链接,就是传统意义上windows中的那种链接,本身可以看做是一种指针,指向实际的文件。

具体ln命令的用法:

ln 源文件 目标文件        //默认创建硬链接

ln -s 源文件 目标文件    //加-s (symbolic)选项创建软链接

创建的软链接在用ls -l 查看的时候是会显示细节的,比如:

1
2
3
4
5
6
7
8
myths@myths-X450LD:~/test$ ln -s a.txt b.txt
myths@myths-X450LD:~/test$ ls
a.txt b.txt
myths@myths-X450LD:~/test$ ls -l
总用量 4
-rw-rw-r-- 1 myths myths 6 11月 6 00:27 a.txt
lrwxrwxrwx 1 myths myths 5 11月 6 00:29 b.txt -> a.txt
myths@myths-X450LD:~/test$

这里权限的第一个位置写的是  l  表明这是一个软链接,而且最后还会有一个箭头指向实际的文件。

当然也可以用readlink 命令来显示链接目的地:

1
2
myths@myths-X450LD:~/test$ readlink  b.txt
a.txt

实际中用到软链接的地方是很多的,比如显示网站的时候,一般将index.html指向实际想执行的文件来默认显示网站打开的网页。

参考文献

NMSU CS课件

Qt中基本的绘图方法

Posted on 2015-11-02 | In Qt

Qt中实现绘图功能和其他的库差不多,主要靠Painter,Pen,Brush之类的东西进行描绘。这里主要牵涉到QPainter,QPen,QBrush三个类,用法也很简单。下面主要是实现一个全面显示各种图形的程序,定义了两个类,一个负责绘图区,一个负责用户交互,这里先介绍绘图区的类。

Painter.pro

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#-------------------------------------------------
#
# Project created by QtCreator 2015-11-02T18:38:46
#
#-------------------------------------------------

QT += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = Painter
TEMPLATE = app

SOURCES += main.cpp
painter.cpp
widget.cpp

HEADERS +=
painter.h
widget.h

painter.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QBrush>
#include<QPen>
#include<QPainter>
#include<QRect>
#include<QPoint>
#include<QDebug>
class Painter : public QWidget
{
Q_OBJECT

public:
Painter(QWidget *parent = 0);
~Painter();
public:
//枚举所有类型的图形
enum Shape{Line,Rectangle,RoundRect,Ellipse,Polygon,Polyline,Points,Arc,Path,Text,Pixmap};
void setShape(Shape);
void setPen(QPen);
void setBrush(QBrush);
//重写重绘事件
void paintEvent(QPaintEvent*);
private :
Shape shape;
QBrush brush;
QPen pen;

};

#endif // WIDGET_H

painter.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#include "painter.h"

Painter::Painter(QWidget *parent)
: QWidget(parent)
{
setPalette(QPalette(Qt::white));//设置背景
setAutoFillBackground(true);
setMinimumSize(400,400);
}

Painter::~Painter()
{

}

void Painter::setShape(Shape s){
shape=s;
update();//调用qwidget的update()来更新状态
}

void Painter::setPen(QPen p){
pen=p;
update();

}

void Painter::setBrush(QBrush b){
brush=b;
update();
}

void Painter::paintEvent(QPaintEvent *){
qDebug()<<"debug 2";

QPainter p(this);//拿到当前的画笔句柄

p.setPen(pen);
p.setBrush(brush);

//留一个Qrect备用
QRect rect(50,100,300,200);

//留一个QPoint 数组备用
static const QPoint points[4]={
QPoint(150,100),
QPoint(300,150),
QPoint(350,250),
QPoint(100,300),
};

//留几个角度备用
int startAngle=30*16;
int spanAngle=120*16;

//留一个QPainterPath备用
QPainterPath path;
path.addRect(150,150,100,100);
path.moveTo(100,100);
path.cubicTo(300,100,200,200,300,300);
path.cubicTo(100,300,200,200,100,100);

//根据选择的shape分别显示
switch(shape){
case Line://直线
p.drawLine(rect.topLeft(),rect.bottomRight());
break;
case Rectangle://矩形
p.drawRect(rect);
break;
case RoundRect://圆角矩形
p.drawRoundRect(rect);
break;
case Ellipse://椭圆
p.drawEllipse(rect);
break;
case Polygon://多边形
p.drawPolygon(points,4);
break;
case Polyline://多边线
p.drawPolyline(points,4);
break;
case Points://点
p.drawPoints(points,4);
break;
case Arc://弧线
p.drawArc(rect,startAngle,spanAngle);
break;
case Path://路径
p.drawPath(path);
break;
case Text://文字
p.drawText(rect,Qt::AlignCenter,"Hello Qt!");
break;
// case Pixmap://图片
// p.drawPixmap(150,150,QPixmap("homemythstest.png"));
// break;
default:
break;
}
}

main.cpp

1
2
3
4
5
6
7
8
9
10
11
#include "painter.h"
#include <QApplication>

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

return a.exec();
}

Visual Studio 系列调试方法整理

Posted on 2015-10-31 | In C/C++

学编程不会调试,这简直就跟做买卖不会数钱一样好笑,有时候程序出了bug,思维受限的时候,肉眼是很难判断出错误的地方的,虽然调试不一定非得用Debug模式来进行,但是使用vs系列的Debug模式的确是个比较方便的好办法。

首先介绍一些快捷键:

Ctrl + F5 键

这个就是直接运行程序,不会在任何断点处下来,所以实际上并不属于Debug模式的范畴,而是直接运行程序了。这样运行的程序结束后会自动pause一下,所以比较方便的能查看程序运行的结果,而不会出现所谓的“闪退”。

开启Debug模式

F5键

表示开始调试,如果程序设置了断点,或者需要从控制台读入数据,那么会在断电处或者输入数据的地方停止下来,否则将运行程序直到结束,而当程序结束的时候,他会直接结束调试模式,可以说是一种“闪退”,这是正常现象。这个键我个人一般不会用,通常会用F10来ctrl+F10来代替。

F10键

单步执行(逐过程),按下F10键后,会在代码的左边出现一个箭头,表示当前程序运行到的地方(当前行并未执行)。每按一次,程序就会向下运行一行,直到程序结束。注意当运行到调用函数的地方的时候,会跳过函数体的内部的运行细节而直接运行到函数返回后的结果。

Ctrl + F10 键

直接运行到光标所在位置(光标所在位置不表示鼠标指针所在位置。。不要犯傻哦),简单暴力。

F11键

单步执行(逐语句),基本作用与F10一样,唯一的不同是,当运行到调用函数的时候,按下该键会直接进入函数体内部,比如scanf函数之类的(这显然是我们不需要知道的),一般情况下如果我们确实想进入函数内部看看,我都会直接用Ctrl + F10直接进去,而不是F11 F11的慢慢走。

F9键

设置和取消断点,会在当前代码行前出现一个红点点,当然直接在代码行前单击一下也可以设置和取消断点,所以这个键比较鸡肋,也不常用。


通过以上的方法,我们进入了Debug模式,进入了这个模式,我们就可以做很多事情了,最简单的事情就是查看单个变量运行时的值。想要做到这一点我们只需要把鼠标指针移到想要查看的光标上,光标旁边就会出现他的值了:

当然,如果想查看一个数组各个元素的值,我们可以把鼠标放在数组名上,就会出现这样的下拉界面:

就可以方便的看到了各个数值了。

当然,如果想更加清楚的看各个数字的变化的话,我们可以调出添加监视的界面。右键某一个变量,选择添加监视:

点开后这样就会出现一下的一个界面:

这个窗口的“名称”部分,我们可以写入我们需要查看的变量的名字,右边会显示他对应的当前的值。如果名字是一个数组,那么他的值显示的是他数组的首地址(没什么卵用),但是我们可以点开名称前面的小三角,来显示出数组中各个元素的值。

关闭Debug模式

在Debug模式下,点击窗口的红叉叉实际上是关闭不了的,我们当然可以在菜单中选择停止调试,但是这样显然很cuo(第二声)(实际上按按钮的行为都很cuo(第二声),所以我把我的按钮那一栏都直接取消了,是不是看上去非常干净0.0),快捷的做法是按shift + F5 这样就可以结束Debug模式而到正常的码代码的模式了。


以上是最基本的Debug方法了,这是最基本的调试方法,每一个人都必须要掌握。

以下是一些比较高级的调试手段了,说高级,并不是说有多难掌握,只是说相对于基础的调试方法来说,这种方法更加快捷,方便程序员使用,他们的关系,我觉得就像各种运行库之于操作系统所提供的API一样,前者是对后者的封装和简化,有兴趣的同学可以来研究研究。

当我们右键设置的断点的时候,我们会发现这样的菜单:

这里我们常用的就是 “条件”选项,和“命中次数”选项,我说了,由于这是“高级”调试手段,所以操作界面十分的User-friendly,应该打开就会用了,我就不赘述了。

注:

  • 个人比较建议大家不要用按钮(这样显得特别的怂),多用快捷键,这样会提高很多的效率。
  • 建议大家都把行号加起来(具体方法请自行百度)
  • 有兴趣的同学可以用一个叫VassistX的插件来辅助你的vs2010(好处谁用谁知道),或者升级到vs2013

Qt中LNK2019错误的解决办法

Posted on 2015-10-30 | In Qt

在写Qt 网络编程的程序时,有时候会遇到

1
dialog.obj:-1: error: LNK2019: 无法解析的外部符号 "__declspec(dllimport) public: virtual __cdecl QNetworkAccessManager::~QNetworkAccessManager(void)" (__imp\_??1QNetworkAccessManager@@UEAA@XZ),该符号在函数 "protected: void __cdecl Dialog::slotLogin(void)" (?slotLogin@Dialog@@IEAAXXZ) 中被引用

这类的错误,让人十分头大。

这个错误大多是因为没有按照要求导入相应的链接库,以至于无法调用相应的类库。在vs或者codeblocks环境下可以通过选项设置之类的东西添加相应的链接库。但是在Qt Creator默认是没有这种东西的,而是提供了另一种途径,即每个项目必然会有的.pro文件,类似于:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#-------------------------------------------------
#
# Project created by QtCreator 2015-10-29T23:52:56
#
#-------------------------------------------------

QT += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = Dialog
TEMPLATE = app

SOURCES += main.cpp
dialog.cpp

HEADERS += dialog.h

这个文件主要是给qmake用的,具体也没有必要了解。一般是系统生成的默认值就行了,只有当我们需要导入链接库的时候才有用。比如当我们需要用QNetworkAccessManager这个类的时候,我们需要在这当中加入一句话:QT += network即可,这样在构建的时候就会导入network这一系列的库。这个network从哪来的呢?实际上,在Qt Creator自带的帮助文档中已经告诉我们了,在QNetworkAccessManager中有相应的说明:

1
2
3
4
Header:		#include <QNetworkAccessManager>
qmake: QT += network
Since: Qt 4.4
Inherits: QObject

有了这个说明,那么解决方案就很明显了。

但是还有一点需要注意,就是在修改过.pro 文件之后,需要手动将系统之前在上一级目录下生成出来的build文件夹删除之后才能使该文件生效。

Qt实现FTP的上传和下载

Posted on 2015-10-29 | In Qt

本来想简单抄抄书,随便手写个Ftp客户端的,结果发现教材上的是基于Qt4的QFtp类库,而在Qt5中取消了这一个类库(同时也取消了QHttp等的类),取而代之的是QNetworkAccessManager 这个类,把这些杂货全都揽下来了,据说是因为之前的两个类有重复而且效率有问题balabala。于是就百度了一下,发现百度上要么讲的不全,要么就是要去下一个由热心网民重新封装的QFtp类。显然我并不喜欢无脑复制粘贴,想好好看下Qt官方提供的东西的用法,深入的理解下Qt网络编程,于是就果断自行google(话说google真好用),加上查看帮助文档,终于把一个简版的Ftp客户端大概框架弄清楚了。

不多说,上源码:

Dialog.pro

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#-------------------------------------------------
#
# Project created by QtCreator 2015-10-29T23:52:56
#
#-------------------------------------------------

QT += core gui
QT += network #这里要添加这个库

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = QFtp
TEMPLATE = app

SOURCES += main.cpp
dialog.cpp

HEADERS += dialog.h

dialog.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#ifndef DIALOG_H
#define DIALOG_H

//注意需要添加的头文件
#include<QDialog>
#include<QPushButton>
#include<QFile>
#include<QNetworkReply>
#include<QLineEdit>
#include<QtNetwork/QNetworkAccessManager>
#include<QtNetwork/QNetworkRequest>
#include<QLabel>
#include<QString>
#include<QGridLayout>
#include<QMessageBox>
class Dialog : public QDialog
{
Q_OBJECT

public:
Dialog(QWidget *parent = 0);
~Dialog();
public:
QGridLayout *layout;
QLabel *LbServer,*LbUser,*LbPasswd;
QLineEdit *LeServer,*LeUser,*LePasswd;
QPushButton *PbPut,*PbGet;
QNetworkAccessManager manager;//这个是重点
protected slots:
//处理按钮的点击信号
void slotPut();
void slotGet();
//处理网络连接的信号
void managePut(QNetworkReply*);
void manageGet(QNetworkReply*);
};

#endif // DIALOG_H

dialog.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#include "dialog.h"

Dialog::Dialog(QWidget *parent)
: QDialog(parent)
{
setWindowTitle("My Ftp");

layout=new QGridLayout(this);
LbServer=new QLabel("Server:");
LbUser=new QLabel("User:");
LbPasswd=new QLabel("Passwd:");
LeServer=new QLineEdit("ftp://120.27.41.126/home/myths/1.txt");
LeUser=new QLineEdit("myths");
LePasswd=new QLineEdit("123456");
LePasswd->setEchoMode(QLineEdit::Password);//设置加密显示
PbPut=new QPushButton("Put");
PbGet=new QPushButton("Get");

layout->addWidget(LbServer,0,0);
layout->addWidget(LeServer,0,1);
layout->addWidget(LbUser,1,0);
layout->addWidget(LeUser,1,1);
layout->addWidget(LbPasswd,2,0);
layout->addWidget(LePasswd,2,1);
layout->addWidget(PbPut,3,0);
layout->addWidget(PbGet,3,1);

setFixedSize(300,200);//固定大小

//按钮点击事件信号槽的连接
connect(PbPut,SIGNAL(clicked()),this,SLOT(slotPut()));
connect(PbGet,SIGNAL(clicked()),this,SLOT(slotGet()));

}

void Dialog::managePut(QNetworkReply * reply){
qDebug()<<reply->error();//输出调试信息
switch(reply->error()){//判断连接后的状态
case QNetworkReply::NoError:
QMessageBox::information(this,"Put information","Upload Success!");
break;
case QNetworkReply::HostNotFoundError:
QMessageBox::information(this,"Put information","Host Not Found!");
break;
case QNetworkReply::AuthenticationRequiredError:
QMessageBox::information(this,"Put information","Login Failure!");
break;
default:
QMessageBox::information(this,"Put information","Unknown Failure");
break;
}
}

void Dialog::manageGet(QNetworkReply *reply){
//基本和managerPut类似
qDebug()<<reply->error();
QByteArray data;
switch(reply->error()){
case QNetworkReply::NoError:
data=reply->readAll();//从url中读取文件内容,输出到data中(也可以再将数据写入到文件中,为了方便,这里就权且打印一下吧)
QMessageBox::information(this,"Put information","Upload Success!nThe file you've got is :n"+data);
break;
case QNetworkReply::HostNotFoundError:
QMessageBox::information(this,"Put information","Host Not Found!");
break;
case QNetworkReply::AuthenticationRequiredError:
QMessageBox::information(this,"Put information","Login Failure!");
break;
default:
QMessageBox::information(this,"Put information","Unknown Failure");
break;
}
}

Dialog::~Dialog()
{

}

void Dialog::slotPut(){
//判断信息输入完整
if(LeUser->text().isEmpty()||LePasswd->text().isEmpty()||LeServer->text().isEmpty()){
QMessageBox::warning(this,"Error","Please fill in the information");
return ;
}

//重点!将之前的槽清空并重新连接至需要的
manager.disconnect(SIGNAL(finished(QNetworkReply*)));
//完全清空某对象连接的槽可以用manager.disconnect();
connect(&manager,SIGNAL(finished(QNetworkReply*)),SLOT(managePut(QNetworkReply*)));

//设置登录信息
QUrl url(LeServer->text());
url.setPort(21);
url.setUserName(LeUser->text());
url.setPassword(LePasswd->text());

QByteArray data="This is the test data.n";
/*QNetworkReply *reply=*/
manager.put(QNetworkRequest(url),data);//将data上传到url中,返回的reply将触发网络的连接信号
}

void Dialog::slotGet(){
//基本意义与slotPut类似
if(LeUser->text().isEmpty()||LePasswd->text().isEmpty()||LeServer->text().isEmpty()){
QMessageBox::warning(this,"Error","Please fill in the information");
return ;
}
manager.disconnect(SIGNAL(finished(QNetworkReply*)));
connect(&manager,SIGNAL(finished(QNetworkReply*)),SLOT(manageGet(QNetworkReply*)));
QUrl url(LeServer->text());
url.setPort(21);
url.setUserName(LeUser->text());
url.setPassword(LePasswd->text());
/*QNetworkReply *reply=*/
manager.get((QNetworkRequest(url)));
}

main.cpp

1
2
3
4
5
6
7
8
9
10
11
#include "dialog.h"
#include <QApplication>

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

return a.exec();
}

5、运行截图

权且只显示主界面:

Qt中实现QQ抽屉效果

Posted on 2015-10-28 | In Qt

本节主要介绍利用QToolBox类实现抽屉效果。

所谓抽屉效果,就是类似QQ的好友分组的效果,每一个分组都可以独立打开和折叠。这样可以以一种动态直观的方式在有限大小的界面上扩展出更多的功能。

具体用法见代码:

Dialog.pro

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#-------------------------------------------------
#
# Project created by QtCreator 2015-10-24T17:32:35
#
#-------------------------------------------------

QT += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = Dialog
TEMPLATE = app

SOURCES += main.cpp
dialog.cpp

HEADERS +=
dialog.h
</pre>
2、dialog.h
<pre class="minimize:true lang:c++ decode:true">#ifndef DIALOG_H
#define DIALOG_H

#include<QDialog>
#include<QVBoxLayout>
#include<QGroupBox>
#include<QToolBox>
#include<QToolButton>
class Drawer : public QToolBox//注意这里是继承自QToolBox。。
{
Q_OBJECT

public:
Drawer(QWidget *parent = 0);
~Drawer();
public:
QToolButton *tBtn1[5],*tBtn2[2],*tBtn3[2];//QToolButton类主要用于设置在工具栏中快速访问的按钮,这里姑且用一下。
QGroupBox *groupBox[3];//这里QGroupBox是用来组织各个按钮的。
QVBoxLayout *layout;//这里用QVBoxLayout来处理各个QGroupBox
};

#endif // DIALOG_H

dialog.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#include "dialog.h"

Drawer::Drawer(QWidget *parent)
: QToolBox(parent)
{
setWindowTitle("The Drawer");

groupBox[0]=new QGroupBox;
groupBox[1]=new QGroupBox;
groupBox[2]=new QGroupBox;

layout=new QVBoxLayout(groupBox[0]);//用layout来处理每个groupbox
layout->setMargin(10);
layout->setAlignment(Qt::AlignHCenter);//设置对齐模式
for(int i=0;i<5;i++){
tBtn1[i]=new QToolButton;
tBtn1[i]->setText("Button"+QString().setNum(i+1)+"nnnnn");
layout->addWidget(tBtn1[i]);//在groupbox中加入按钮
}
layout->addStretch();//拉伸布局,使部件能够对齐

layout=new QVBoxLayout(groupBox[1]);
layout->setMargin(10);
layout->setAlignment(Qt::AlignHCenter);
for(int i=0;i<2;i++){
tBtn2[i]=new QToolButton;
tBtn2[i]->setText("Button"+QString().setNum(i+1));
layout->addWidget(tBtn2[i]);
}
layout->addStretch();

layout=new QVBoxLayout(groupBox[2]);
layout->setMargin(10);
layout->setAlignment(Qt::AlignHCenter);
for(int i=0;i<2;i++){
tBtn3[i]=new QToolButton;
tBtn3[i]->setText("Button"+QString().setNum(i+1));
layout->addWidget(tBtn3[i]);
}
layout->addStretch();

this->addItem(groupBox[0],"family");//在当前的QToolBox中添加部件即可
this->addItem(groupBox[1],"friends");
this->addItem(groupBox[2],"strangers");
}
Drawer::~Drawer()
{

}

运行截图



Qt中各种消息框的使用

Posted on 2015-10-27 | In Qt

在程序运行时,经常需要提示用户一些信息,比如警告啊,提示啊,建议啊之类的东西。这些东西基本上是通过消息框与用户进行交互的,Qt中主要是用QMessageBox类来加以实现的。

消息框一般分为七种:

  1. Question询问消息框:为正常的操作提供一个简单的询问
  2. Information信息消息框:为正常操作提供一个提示
  3. Warning提示消息框:提醒用户发生了一个错误
  4. Critical警告消息框:警告用户发生了一个严重错误
  5. About关于消息框:自定义的关于信息
  6. AboutQt关于Qt消息框:Qt自身的关于信息
  7. Custom自定义消息框:自己定制消息框

具体用法见源码以及分析:

Dialog.pro

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#-------------------------------------------------
#
# Project created by QtCreator 2015-10-24T17:32:35
#
#-------------------------------------------------

QT += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = Dialog
TEMPLATE = app

SOURCES += main.cpp
dialog.cpp

HEADERS += dialog.h

dialog.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#ifndef DIALOG_H
#define DIALOG_H

#include <QDialog>
#include<QGridLayout>
#include<QPushButton>
#include<QLabel>
#include<QMessageBox>
class Dialog : public QDialog
{
Q_OBJECT

public:
Dialog(QWidget *parent = 0);
~Dialog();
public://配置部件和布局
QLabel *label;
QPushButton *QuestionBtn,*InformationBtn,*WarningBtn,*CriticalBtn,*AboutBtn,*AboutQtBtn,*CustomBtn;
QGridLayout *layout,*layoutLabel,*layoutBtn;
protected slots://各种按钮的槽
void slotQuestion();
void slotInformation();
void slotWarning();
void slotCritical();
void slotAbout();
void slotAboutQt();
void slotCustom();
};

#endif // DIALOG_H

dialog.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#include "dialog.h"

Dialog::Dialog(QWidget *parent)
: QDialog(parent)
{
setWindowTitle("QMessageBox");

QuestionBtn=new QPushButton("Question");
InformationBtn=new QPushButton("Information");
WarningBtn=new QPushButton("Warning");
CriticalBtn=new QPushButton("Critical");
AboutBtn=new QPushButton("About");
AboutQtBtn=new QPushButton("AboutQt");
CustomBtn=new QPushButton("Custom");

label=new QLabel("About Qt MessageBox:");
layout=new QGridLayout(this);
layoutLabel=new QGridLayout;
layoutBtn=new QGridLayout;
layoutLabel->addWidget(label,0,0);
layoutBtn->addWidget(QuestionBtn,1,0);
layoutBtn->addWidget(InformationBtn,1,1);
layoutBtn->addWidget(WarningBtn,2,0);
layoutBtn->addWidget(CriticalBtn,2,1);
layoutBtn->addWidget(AboutBtn,3,0);
layoutBtn->addWidget(AboutQtBtn,3,1);
layoutBtn->addWidget(CustomBtn,4,0);
layoutBtn->setSpacing(15);

//嵌套布局
layout->addLayout(layoutLabel,0,0);
layout->addLayout(layoutBtn,1,0);
setFixedSize(300,220);//固定大小

connect(QuestionBtn,SIGNAL(clicked()),this,SLOT(slotQuestion()));
connect(InformationBtn,SIGNAL(clicked()),this,SLOT(slotInformation()));
connect(WarningBtn,SIGNAL(clicked()),this,SLOT(slotWarning()));
connect(CriticalBtn,SIGNAL(clicked()),this,SLOT(slotCritical()));
connect(AboutBtn,SIGNAL(clicked()),this,SLOT(slotAbout()));
connect(AboutQtBtn,SIGNAL(clicked()),this,SLOT(slotAboutQt()));
connect(CustomBtn,SIGNAL(clicked()),this,SLOT(slotCustom()));
}

Dialog::~Dialog()
{

}

//直接调用AboutQt,设置句柄和标题即可
void Dialog::slotAboutQt(){
QMessageBox::aboutQt(this,"This is the title");
}

//以下三个函数均是设置句柄标题和信息即可,也可以在最后设置默认按钮,一般默认的是QMessageBox::Ok。
void Dialog::slotAbout(){
QMessageBox::about(this,"About","This is the label.");
}
void Dialog::slotCritical(){
QMessageBox::critical(this,"Critical","This is the label.");
}
void Dialog::slotInformation(){
QMessageBox::information(this,"Information","This is the label.");
}

//自定义消息框
void Dialog::slotCustom(){

QMessageBox customMsgBox;
customMsgBox.setWindowTitle("Custom message box");

//添加按键
QPushButton *lockBtn=customMsgBox.addButton("Lock",QMessageBox::ActionRole);
QPushButton *unlockBtn=customMsgBox.addButton("Unlock",QMessageBox::ActionRole);
QPushButton *cancelBtn=customMsgBox.addButton(QMessageBox::Cancel);//注意cancel不能指定Text

//customMsgBox.setIconPixmap(QPixmap("a.png"));//设置图片
customMsgBox.setText("This is the label");
customMsgBox.exec();//执行消息框

QPushButton *msg=(QPushButton*)customMsgBox.clickedButton();//接受按键信息

//判断按键
if(msg==lockBtn)
label->setText("Custom button /lock");

if(msg==unlockBtn)
label->setText("Custom button /unlock");

if(msg==cancelBtn)
label->setText("Custom button /cancel");

}

void Dialog::slotQuestion(){
//QMessageBox::**question()**函数,传入句柄,标题,文本,按钮值,返回按键对应的值,最后也可以加默认按键的位置
int msg=QMessageBox::question(this,"Question","This is the label.",QMessageBox::Ok|QMessageBox::Cancel);

//判断选择信息
switch(msg){
case QMessageBox::Ok:
label->setText("Question button /OK");
break;
case QMessageBox::Cancel:
label->setText("Question button /Cancel");
break;
default:
break;
}
}

void Dialog::slotWarning(){

//QmessageBox::warning()函数同Question函数
int msg=QMessageBox::warning(this,"Question","This is the label.",QMessageBox::Save|QMessageBox::Discard|QMessageBox::Cancel,QMessageBox::Save);

switch(msg){//判断选择信息
case QMessageBox::Save:
label->setText("Warning button /Save");
break;
case QMessageBox::Cancel:
label->setText("Warning button /Cancel");
break;
case QMessageBox::Discard:
label->setText("Warning button /Discard");
break;
default:
break;
}

}

##main.cpp

1
2
3
4
5
6
7
8
9
10
11
#include "dialog.h"
#include <QApplication>

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

return a.exec();
}

运行截图







1…535455…58

574 posts
69 categories
286 tags
© 2024 Companyd
Powered by Hexo
|
Theme — NexT.Muse v5.1.4