基于easyx的按钮

才开始学习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

新人文章多多关照,不足的地方希望各位大佬提出

  • 9
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
在使用EasyX库进行图形界面开发时,可以通过将每一个页面与唯一一个数字进行对应,然后在每次发生鼠标事件时,检测对应页面下的按钮事件,即可实现点击按钮跳转页面的功能。 以下是一个示例代码,展示了如何使用EasyX库来实现点击按钮跳转页面的功能: ``` #include <graphics.h> // 定义页面编号常量 const int PAGE_MENU = 1; const int PAGE_GAME = 2; // 当前页面变量,初始为菜单页面 int currentPage = PAGE_MENU; // 菜单页面的按钮坐标和尺寸 int menuButtonX = 100; int menuButtonY = 100; int menuButtonWidth = 200; int menuButtonHeight = 50; // 游戏页面的按钮坐标和尺寸 int gameButtonX = 100; int gameButtonY = 200; int gameButtonWidth = 200; int gameButtonHeight = 50; // 鼠标事件处理函数 void mouseProc(int x, int y, int button, int event) { if (currentPage == PAGE_MENU) { // 如果当前页面是菜单页面 if (button == MOUSE_LEFT && event == MOUSE_DOWN) { // 当鼠标左键按下时 if (x >= menuButtonX && x <= menuButtonX + menuButtonWidth && y >= menuButtonY && y <= menuButtonY + menuButtonHeight) { // 如果鼠标点击在菜单按钮范围内 currentPage = PAGE_GAME; // 跳转到游戏页面 } } } } int main() { // 初始化图形界面 initgraph(640, 480); // 注册鼠标事件处理函数 setmousequeuestatus(WM_LBUTTONDOWN); setbkcolor(WHITE); while (true) { // 绘制当前页面 if (currentPage == PAGE_MENU) { // 绘制菜单页面 cleardevice(); outtextxy(menuButtonX, menuButtonY, "Click here to go to the game page."); } else if (currentPage == PAGE_GAME) { // 绘制游戏页面 cleardevice(); outtextxy(gameButtonX, gameButtonY, "This is the game page."); } // 监听鼠标事件 MOUSEMSG msg = GetMouseMsg(); mouseProc(msg.x, msg.y, msg.mkButton, msg.uMsg); // 如果点击关闭按钮,则退出程序 if (msg.uMsg == WM_CLOSE) { break; } } // 关闭图形界面 closegraph(); return 0; } ``` 通过以上代码中的mouseProc函数,我们可以在菜单页面中检测到鼠标左键点击事件,并判断是否点击在菜单按钮范围内,如果是,则将当前页面切换到游戏页面。然后在主循环中根据当前页面的值来绘制相应的页面内容。所以,可以通过这种方式来实现EasyX点击按钮跳转页面的效果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值