【发布时间】:2021-08-14 14:43:37
【问题描述】:
我正在用 C++ wxWidgets 编写一个应用程序。我正在尝试创建一个自定义按钮类,虽然有两个问题:
- 我将 wxEVT_COMMAND_BUTTON_CLICKED 绑定到按钮以在单击时执行功能,但它似乎没有被调用
- 它周围有一个可怕的灰色边框,我无法删除(即使使用 wxBORDER_NONE 也不行)
代码:
gridButton.h
#pragma once
#include "wx/wx.h"
enum gbSTYLE {
NUM,
OP,
EXTRA
};
class gridButton : public wxWindow
{
bool pressed;
bool hovered;
wxString text;
static const int width = 50, height = 50;
wxFont* gbFont = new wxFont(20, wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL,
wxFONTWEIGHT_LIGHT, false, "Lato");
// RICORDATI DI CANCELLARE font_Button DALLA CLASSE MAIN QUANDO HAI FINITO
wxBrush* background;
wxColour* textColor;
wxBrush* hoveredBackground;
wxColour* hoveredTextColor;
wxBrush* pressedBackground;
wxColour* pressedTextColor;
public:
gridButton(wxFrame* parent, wxWindowID id, wxString text, gbSTYLE style);
~gridButton();
void applyStyle(gbSTYLE style);
void paintEvent(wxPaintEvent& evt);
void paintNow();
void render(wxDC& dc);
void mouseMoved(wxMouseEvent& evt);
void mouseDown(wxMouseEvent& evt);
void mouseWheelMoved(wxMouseEvent& evt);
void mouseReleased(wxMouseEvent& evt);
void rightClick(wxMouseEvent& evt);
void mouseLeftWindow(wxMouseEvent& evt);
void mouseEnterWindow(wxMouseEvent& evt);
void keyPressed(wxKeyEvent& evt);
void keyReleased(wxKeyEvent& evt);
DECLARE_EVENT_TABLE()
};
gridButton.cpp
#include "gridButton.h"
BEGIN_EVENT_TABLE(gridButton, wxWindow)
EVT_MOTION(gridButton::mouseMoved)
EVT_LEFT_DOWN(gridButton::mouseDown)
EVT_LEFT_UP(gridButton::mouseReleased)
EVT_RIGHT_DOWN(gridButton::rightClick)
EVT_ENTER_WINDOW(gridButton::mouseEnterWindow)
EVT_LEAVE_WINDOW(gridButton::mouseLeftWindow)
EVT_KEY_DOWN(gridButton::keyPressed)
EVT_KEY_UP(gridButton::keyReleased)
EVT_MOUSEWHEEL(gridButton::mouseWheelMoved)
EVT_PAINT(gridButton::paintEvent)
END_EVENT_TABLE()
// funzione costruttrice (wxFULL_REPAINT_ON_RESIZE per evitare un glitch grafico quando si ridimensiona la finestra)
gridButton::gridButton(wxFrame* parent, wxWindowID id, wxString text, gbSTYLE style)
: wxWindow(parent, id, wxDefaultPosition, wxDefaultSize, wxFULL_REPAINT_ON_RESIZE)
{
SetMinSize(wxSize(width, height));
this->text = text;
hovered = false;
pressed = false;
applyStyle(style);
}
// funzione distruttrice
gridButton::~gridButton()
{
delete gbFont;
delete background;
delete textColor;
delete hoveredBackground;
delete hoveredTextColor;
delete pressedBackground;
delete pressedTextColor;
}
void gridButton::applyStyle(gbSTYLE style)
{
switch (style)
{
default:
background = new wxBrush(wxColour(255, 255, 255), wxBRUSHSTYLE_SOLID);
textColor = new wxColour(25, 25, 25);
hoveredBackground = new wxBrush(wxColour(125, 125, 125), wxBRUSHSTYLE_SOLID);
hoveredTextColor = new wxColour(185, 185, 185);
pressedBackground = new wxBrush(wxColour(25, 25, 25), wxBRUSHSTYLE_SOLID);
pressedTextColor = new wxColour(200, 200, 200);
break;
case NUM:
background = new wxBrush(wxColour(98, 101, 138), wxBRUSHSTYLE_SOLID);
textColor = new wxColour(190, 197, 200);
hoveredBackground = new wxBrush(wxColour(66, 69, 96), wxBRUSHSTYLE_SOLID);
hoveredTextColor = new wxColour(36, 38, 52);
pressedBackground = new wxBrush(wxColour(16, 17, 23), wxBRUSHSTYLE_SOLID);
pressedTextColor = new wxColour(128, 134, 192);
break;
}
}
//chiamato da EVT_PAINT ogni frame
void gridButton::paintEvent(wxPaintEvent& evt)
{
wxPaintDC dc(this);
render(dc);
}
//eseguire un render quando si vuole
void gridButton::paintNow()
{
wxClientDC dc(this);
render(dc);
}
//renderizzazione, qui si mette la grafica
void gridButton::render(wxDC& dc)
{
int w = this->GetSize().GetWidth();
int h = this->GetSize().GetHeight();
if (pressed) {
dc.SetBrush(*pressedBackground);
dc.SetTextForeground(*pressedTextColor);
}
else if (hovered) {
dc.SetBrush(*hoveredBackground);
dc.SetTextForeground(*hoveredTextColor);
}
else {
dc.SetBrush(*background);
dc.SetTextForeground(*textColor);
}
dc.DrawRectangle(0, 0, w, h);
dc.SetFont(*gbFont);
wxSize textSize = GetTextExtent(text);
dc.DrawText(text, w / 2 - (textSize.GetWidth()), h / 2 - (textSize.GetHeight()));
}
void gridButton::mouseDown(wxMouseEvent& evt)
{
pressed = true;
paintNow();
}
void gridButton::mouseReleased(wxMouseEvent& evt)
{
pressed = false;
paintNow();
}
void gridButton::mouseEnterWindow(wxMouseEvent& evt)
{
hovered = true;
paintNow();
}
void gridButton::mouseLeftWindow(wxMouseEvent& evt)
{
hovered = false;
pressed = false;
paintNow();
}
// eventi inutilizzati
void gridButton::mouseMoved(wxMouseEvent& evt) {}
void gridButton::mouseWheelMoved(wxMouseEvent& evt) {}
void gridButton::rightClick(wxMouseEvent& evt) {}
void gridButton::keyPressed(wxKeyEvent& evt) {}
void gridButton::keyReleased(wxKeyEvent& evt) {}
这就是我布局网格的方式(现在看起来很糟糕,因为我仍在处理按钮本身):
#include "main.h"
void Main::AddButtons()
{
int w = 5, h = 4;
MainGrid = new wxGridSizer(w, h, 0, 0);
gridButton* test = new gridButton(this, wxID_ANY, "(", NUM);
MainGrid->Add(test, 0, wxEXPAND);
AddOpButton(4);
for (int i = 0; i < 2; i++) MainGrid->AddSpacer(1);
for (int i = 7; i < 10; i++) AddNumButton(i);
AddOpButton(3);
for (int i = 4; i < 7; i++) AddNumButton(i);
AddOpButton(2);
for (int i = 1; i < 4; i++) AddNumButton(i);
AddOpButton(1);
MainGrid->AddSpacer(1);
AddNumButton(0);
//dot
wxButton* dot = new wxButton(this, wxID_ANY, ".");
dot->SetFont(*font_Button);
dot->SetBackgroundColour(wxColour(200, 200, 200));
dot->SetForegroundColour(wxColour(125, 125, 125));
dot->Bind(wxEVT_COMMAND_BUTTON_CLICKED, &Main::OnDotClicked, this);
MainGrid->Add(dot, 0, wxEXPAND);
AddOpButton(0);
MainSizer->Add(MainGrid, 10, wxEXPAND);
}
void Main::AddNumButton(int n)
{
gridButton* btn = new gridButton(this, BUTTON_NUM + n, wxString(std::to_string(n)), NUM);
btn->Bind(wxEVT_COMMAND_BUTTON_CLICKED, &Main::OnNumClicked, this);
MainGrid->Add(btn, 0, wxEXPAND);
}
void Main::AddOpButton(int n)
{
std::string s(1, ops[n]);
gridButton* btn = new gridButton(this, BUTTON_OP + n, wxString(s), OP);
btn->Bind(wxEVT_COMMAND_BUTTON_CLICKED, &Main::OnOpClicked, this);
MainGrid->Add(btn, 0, wxEXPAND);
}
它应该触发的事件:
void Main::OnNumClicked(wxCommandEvent& evt)
{
int id = evt.GetId() - BUTTON_NUM;
DoNumClick(id);
evt.Skip();
}
void Main::DoNumClick(int id)
{
char c = '0' + id;
char exp[EXPBUFFER];
strcpy(exp, MainText->GetValue());
if (strlen(exp) == 1 && exp[0] == '0')
{
exp[0] = c;
MainText->SetLabel(exp);
}
else
MainText->AppendText(std::to_string(id));
}
我是 wxWidgets 的新手,感谢任何帮助。
【问题讨论】:
标签: c++ events graphics wxwidgets