才开始学习qt,发现按钮类有点意思,于是用easyx封装了一个按钮,顺便实现了简单的计算器功能
按钮
1.抽象按钮(sbutton)
先生成一个按钮的基础属性作为抽象按钮,还可以添加很多功能,比如在按钮上添加图片,待完善
sbutton.h
#pragma once
#include <graphics.h>
#include <iostream>
#include <vector>
#include <string>
class AButton
{
private:
int x;
int y;
int Width;
int Height;
int state;
COLORREF Normal_color;
COLORREF Hover_color;
COLORREF Click_color;
COLORREF Line_color;
string textString;
string textStyle;
enum{NORMAL,HOVER,CLICK};
public:
AButton(int x, int y, int width, int height, COLORREF normal_color=RGB(218, 220, 235), string textString=" ", string textStyle="楷体");
void drawButton(); //绘制按钮
bool isInButton(EASYXMSG m); //是否在按钮上
bool ClickButton(EASYXMSG m); //是否点击按钮
COLORREF& getcolor(); //返回点击按钮当前颜色
string& getText(); //返回点击按钮的文字
void SetLineColor(COLORREF color); //更改线条颜色
double scale; //缩放
void StateColor(int state); //更改颜色
void SetHoverColor(COLORREF color) //设置Hover颜色
{
Hover_color = color;
}
void SetClickColor(COLORREF color)//设置点击颜色
{
Click_color = color;
}
};
sbutton.cpp
#include "sbutton.h"
AButton::AButton(int x, int y, int width, int height, COLORREF normal_color, string textString, string textStyle):
x(x),y(y),Width(width),Height(height), Normal_color(normal_color),textString(textString),textStyle(textStyle)
{
Hover_color = RGB(240, 240, 245);
Click_color = RGB(215, 217, 231);
state = NORMAL;
setlinecolor(Line_color);
scale = 1.0f;
}
void AButton::drawButton()
{
int ScaleHeight = Height * scale;
int ScaleWidth = Width * scale;
int ScaleX = x + (Width - ScaleWidth) / 2;
int ScaleY = y + (Height - ScaleHeight) / 2;
int Font_Height = textheight(textString.c_str());
int Font_Width = textwidth(textString.c_str());
setbkmode(TRANSPARENT);
settextcolor(BLACK);
setlinecolor(Line_color);
settextstyle(20,0, textStyle.c_str());
StateColor(state);
fillrectangle(ScaleX, ScaleY, ScaleX+ScaleWidth, ScaleY + ScaleHeight);
outtextxy(ScaleX + (ScaleWidth - Font_Width) / 2, ScaleY + (ScaleHeight - Font_Height) / 2, textString.c_str());
}
bool AButton::isInButton(EASYXMSG m)
{
int ScaleHeight = Height * scale;
int ScaleWidth = Width * scale;
int ScaleX = x + (Width - ScaleWidth) / 2;
int ScaleY = y + (Height - ScaleHeight) / 2;
if (m.x >= ScaleX && m.x<=ScaleX + ScaleWidth && m.y>ScaleY && m.y <= ScaleY + ScaleHeight)
{
scale = 0.9f;
state = HOVER;
return true;
}
scale = 1.0f;
state = NORMAL;
return false;
}
bool AButton::ClickButton(EASYXMSG m)
{
if (isInButton(m))
{
scale = 0.9f;
state = CLICK;
return true;
}
scale = 1.0f;
state = NORMAL;
return false;
}
COLORREF& AButton::getcolor()
{
return Normal_color;
}
string& AButton::getText()
{
return textString;
}
void AButton::SetLineColor(COLORREF color)
{
Line_color = color;
}
void AButton::StateColor(int state)
{
switch (state)
{
case NORMAL:
setfillcolor(Normal_color);
break;
case HOVER:
setfillcolor(Hover_color);
break;
case CLICK:
setfillcolor(Click_color);
break;
}
}
2.具体的按钮类
在这个类中用vector容器装抽象按钮,并且批量的对这些抽象按钮实现按键控制,可以通过这个类中的AddButton函数实现添加一个按钮。但还缺少对某一个按键的控制,也待完善
button.h
class Button
{
private:
vector<AButton*>button; //存放点击按钮颜色
string text; //文本
bool IsClick; //是否点击按钮
void Draw(); //画出容器中的按钮
COLORREF line_color; //设置边框的颜色
public:
Button() :IsClick(false) {};
~Button() { button.clear(); }
void AddButton(int x, int y, int width, int height, COLORREF color = RGB(218, 220, 235),
string textString = " ", string textStyle = "宋体");
void MouseOperate();
bool getIsClick();
string gettext()
{
return text.empty() ? "" : text;
}
void PrintText()
{
if (!text.empty()) cout << text << " ";
}
void SetButtonLine(COLORREF color);
};
button.cpp
void Button::Draw()
{
cleardevice();
for (auto it = button.begin(); it != button.end(); it++)
{
(*it)->drawButton();
}
}
void Button::AddButton(int x, int y, int width, int height, COLORREF color, string textString, string textStyle)
{
AButton* button = new AButton(x, y, width, height, color, textString, textStyle);
this->button.push_back(button);
button->SetLineColor(line_color);
button->drawButton();
}
void Button::MouseOperate()
{
this->text = "";
ExMessage msg;
while (peekmessage(&msg, EX_MOUSE))
{
if (msg.message == WM_LBUTTONDOWN)
{
for (auto it = this->button.begin(); it != button.end(); it++)
{
if ((*it)->ClickButton(msg))
{
this->text = (*it)->getText();
IsClick = true;
/*cout << "click" << endl;*/
}
}
}
else if (msg.message = WM_MOUSEMOVE)
{
for (auto it = this->button.begin(); it != button.end(); it++)
{
if ((*it)->isInButton(msg))
{
/*cout << "move" << endl;*/
}
}
}
Draw();
}
}
bool Button::getIsClick()
{
return this->IsClick;
}
void Button::SetButtonLine(COLORREF color)
{
line_color = color;
for (auto it = button.begin(); it != button.end(); it++)
{
(*it)->SetLineColor(color);
}
}
通过按钮实现简单计算器
计算器类
通过栈的方式实现加减乘除运算
calculator.h
#pragma once
#include <iostream>
#include <vector>
#include <string>
using namespace std;
class Calculator
{
public:
string calculator(string s);
string transform(double result);
bool IsNum(char s);
double AddNum(vector<double>num);
bool IsInputSign(string sign);
};
calculator.cpp
#include "calculator.h"
string Calculator::calculator(string s) {
double n = s.size(), dgt = 0;
char preSign = '+';//第一个数是正的
vector<double> v;
int num = 1; //小数点
bool IsPoint = false;
for (int i = 0; i < n; i++) {
if (!IsNum(s[i])) preSign = s[i], num = 1, IsPoint = false;
else {
while (IsNum(s[i]))
{
if (s[i] == '.') i++, IsPoint = true;
if (IsPoint)
{
dgt = dgt + (s[i] - '0') * pow(0.1, num);
num++;
}
else dgt = dgt * 10 + s[i] - '0';
i++;
cout << "dgt==" << dgt << endl;
}
cout << "num=" << dgt << endl;
cout << "symbol=" << preSign << endl;
if (preSign == '+') v.push_back(dgt);
if (preSign == '-') v.push_back(-dgt);
if (preSign == '*') v.back() *= dgt;
if (preSign == '/') v.back() /= dgt;
dgt = 0, i--;
}
}
for (auto it = v.begin(); it != v.end(); it++)
{
cout << *it << " ";
}
double result = AddNum(v);
cout << "result=" << result << endl;
return transform(result);
}
string Calculator::transform(double result)
{
string sum;
sum.push_back('=');
string temp = to_string(result);
sum += temp;
for (auto it = sum.end() - 1; it != sum.begin(); it--)
{
if (*it == '0') sum.pop_back();
else break;
}
cout << "sum=" << sum << endl;
return sum;
}
bool Calculator::IsNum(char s)
{
return (s >= '0' && s <= '9') || s == '.';
}
double Calculator::AddNum(vector<double> num)
{
double result = 0.0f;
for (auto it = num.begin(); it != num.end(); it++)
{
result += *it;
}
return result;
}
bool Calculator::IsInputSign(string sign)
{
bool IsSign = false;
if (sign == "-") IsSign = true;
else if (sign == "+") IsSign = true;
else if (sign == "*")IsSign = true;
else if (sign == "/")IsSign = true;
else IsSign = false;
return IsSign;
}
main.cpp
最后的main函数
#define _CRT_SECURE_NO_WARNINGS
#include "sbutton.h"
#include "calculator.h"
#include <algorithm>
#include <numeric>
#include <ctime>
void addbutton(Button* button)
{
button->AddButton(0, 380, 100, 100, WHITE, "+","Segoe UI Emoji");
button->AddButton(100, 380, 100, 100, WHITE, "0", "Segoe UI Emoji");
button->AddButton(200, 380, 100, 100, WHITE, ".", "Segoe UI Emoji");
button->AddButton(300, 380, 100, 100, WHITE, "=", "Segoe UI Emoji");
button->AddButton(0, 280, 100, 100, WHITE, "1", "Segoe UI Emoji");
button->AddButton(100, 280, 100, 100, WHITE, "2", "Segoe UI Emoji");
button->AddButton(200, 280, 100, 100, WHITE, "3", "Segoe UI Emoji");
button->AddButton(300, 280, 100, 100, WHITE, "-", "Segoe UI Emoji");
button->AddButton(0, 180, 100, 100, WHITE, "4", "Segoe UI Emoji");
button->AddButton(100, 180, 100, 100, WHITE, "5", "Segoe UI Emoji");
button->AddButton(200, 180, 100, 100, WHITE, "6", "Segoe UI Emoji");
button->AddButton(300, 180, 100, 100, WHITE, "/", "Segoe UI Emoji");
button->AddButton(0, 80, 100, 100, WHITE, "7", "Segoe UI Emoji");
button->AddButton(100, 80, 100, 100, WHITE, "8", "Segoe UI Emoji");
button->AddButton(200, 80, 100, 100, WHITE, "9", "Segoe UI Emoji");
button->AddButton(300, 80, 100, 100, WHITE, "*", "Segoe UI Emoji");
button->AddButton(400, 380, 100, 100, WHITE, "AC", "Segoe UI Emoji");
}
void initsetting()
{
BeginBatchDraw();
Button* Init = new Button;
Init->SetButtonLine(WHITE);
Init->AddButton(100, 300, 300, 50, WHITE, "开始");
Init->AddButton(50, 10, 400, 200, WHITE, "计算器0.1","华文琥珀");
while (!Init->getIsClick())
{
Init->MouseOperate();
FlushBatchDraw();
}
EndBatchDraw();
for (int i = 100; i < 236; i++)
{
setbkcolor(RGB(i, i, i));
cleardevice();
Sleep(1);
}
setbkcolor(WHITE);
cleardevice();
}
int main()
{
initgraph(500, 480);
ShowCursor(true);
HWND hwnd = GetHWnd();
SetWindowText(hwnd, "calcultor");
setbkcolor(WHITE);
cleardevice();
initsetting();
Button* button = new Button;
Calculator calculate;
addbutton(button);
string formula; //公式
bool IsSign = false; //判断是否按下运算符号
BeginBatchDraw();
while (1)
{
line(textwidth(formula.c_str())+8, 12, textwidth(formula.c_str())+8, 28);
button->MouseOperate();
button->PrintText();
if (!button->gettext().empty())
{
if (button->gettext() != "=")
formula += button->gettext();
else
{
formula = calculate.calculator(formula);
}
if (calculate.IsInputSign(button->gettext()) && IsSign)
{
formula[formula.length() - 2] = formula.back();
formula.pop_back();
}
IsSign=calculate.IsInputSign(button->gettext());
}
if (button->gettext() == "AC") formula.clear();
outtextxy(5, 10, formula.c_str());
FlushBatchDraw();
}
EndBatchDraw();
}
成品展示
顺便给b站视频点个赞吧
https://t.bilibili.com/917195471573745680?share_source=pc_native
新人文章多多关照,不足的地方希望各位大佬提出