Я пытаюсь создать пользовательские кнопки для графического интерфейса с помощью wxwidgets

Я пытаюсь сделать простой графический интерфейс с двумя пользовательскими кнопками. Две кнопки сделаны в виде панелей, и я не могу заставить панели менять цвет, когда я нажимаю на них. На данный момент они дают тот же результат, когда я нажимаю их, но это должно измениться, но я тоже не уверен, как на данный момент.

Это код, и если у вас есть идея, как я могу решить свою проблему, я буду признателен за ваш вклад: D.

PS: В коде есть несколько #Include <wx/wx.h> и так далее, потому что я создаю файлы .h для своих классов!

Изображение GUI код дает:

#include <wx/wx.h>

class MyPanel : public wxPanel {

    bool pressedDown;
    wxString text;


    public:
    MyPanel(wxWindow *parent, wxString text);

    void paintEvent(wxPaintEvent & evt);
    void paintNow();
        
    void render(wxDC& dc);
        
    // some useful events
    
    void mouseDown(wxMouseEvent& event);
    void mouseReleased(wxMouseEvent& event);
    void mouseLeftWindow(wxMouseEvent& event);
        
    DECLARE_EVENT_TABLE()


}; 

#include "Panels.h"
#include <iostream>

BEGIN_EVENT_TABLE(MyPanel,wxWindow)

    EVT_LEFT_DOWN(MyPanel::mouseDown)
    EVT_LEFT_UP(MyPanel::mouseReleased)
    EVT_LEAVE_WINDOW(MyPanel::mouseLeftWindow)
    

    // catch paint events
    EVT_PAINT(MyPanel::paintEvent)

END_EVENT_TABLE()

MyPanel::MyPanel(wxWindow *parent, wxString text) : wxPanel(parent, wxID_ANY){
    this->text = text;
    pressedDown = false;
}

void MyPanel::paintEvent(wxPaintEvent & evt)
{
    // depending on your system you may need to look at double-buffered dcs
    wxPaintDC dc(this);
    render(dc);
}

void MyPanel::paintNow()
{
    // depending on your system you may need to look at double-buffered dcs
    wxClientDC dc(this);
    render(dc);
}

void MyPanel::render(wxDC&  dc)
{
    if (pressedDown)
        dc.SetBrush( *wxRED_BRUSH );
        else
        dc.SetBrush( *wxGREY_BRUSH );
    
    dc.DrawText( text, 20, 15 );
}

void MyPanel::mouseDown(wxMouseEvent& event)
{
    pressedDown = true;
    paintNow();
}

void MyPanel::mouseReleased(wxMouseEvent& event)
{
    pressedDown = false;
    paintNow();

    std::cout << "Pressed" << std::endl;
}
void MyPanel::mouseLeftWindow(wxMouseEvent& event)
{
    if (pressedDown)
    {
        pressedDown = false;
        paintNow();
    }
}

#include <wx/wx.h>

class AppFrame : public wxFrame
{
public:
   AppFrame(const wxString& title, const wxPoint &pos, const wxSize &size);

};

#include <wx/wx.h>
#include "AppFrame.h"
#include "Panels.h"

MyPanel* m_btn_1;
MyPanel* m_btn_2;


AppFrame::AppFrame(const wxString &title, const wxPoint &pos, const wxSize &size)
: wxFrame(nullptr, wxID_ANY, title, pos, size) {

    wxInitAllImageHandlers();
    
    m_btn_1 = new MyPanel( this, wxT("PickUp") );
    m_btn_1->SetBackgroundColour(wxColor(100, 100, 200));

    m_btn_2 = new MyPanel( this, wxT("PlaceDown") );
    m_btn_2->SetBackgroundColour(wxColor(100, 200, 100));

    wxBoxSizer *sizer = new wxBoxSizer(wxVERTICAL);
    sizer->Add(m_btn_1, 1, wxEXPAND | wxLEFT | wxTOP | wxRIGHT, 10);
    sizer->Add(m_btn_2, 1, wxEXPAND | wxALL, 10);

    this->SetSizerAndFit(sizer);
Centre();
}

#include <wx/wx.h>

class App : public wxApp
{
public:
   virtual bool OnInit();
};
 
// This defines the equivalent of main() for the current platform.
DECLARE_APP(App);

#include "main.h"
#include <wx/wx.h>
#include "AppFrame.h"

IMPLEMENT_APP(App)

bool App::OnInit(){
    AppFrame *frame = new AppFrame("Frame",wxDefaultPosition,wxDefaultSize);
    frame->Show(true);
    return true;
}


Нужно ли делать кнопки как кастомные панели? Нельзя ли просто использовать встроенный тип кнопки и менять цвет фона в ответ на щелчок?

avariant 18.04.2023 00:22

Я очень новичок в этом, и я просто пробую что-то, глядя на эксампели, и поэтому я не знаю, что возможно. Если у вас есть пример, я хотел бы увидеть его. Я как бы пытаюсь сделать что-то, что я придумал в уме. Я загружаю изображение того, что дает код при компиляции: D.

user13170084 18.04.2023 00:31

Существует довольно много примеров wxWidgets. Базовый тип wxButton имеет методы SetBackgroundColor, SetForegroundColor и SetLabel. Это может быть все, что вам нужно. docs.wxwidgets.org/3.0/classwx_button.html

avariant 18.04.2023 00:34

Кстати, сообщение очень похоже на то, что вы пытаетесь сделать здесь, на форуме wxWidgets: forums.wxwidgets.org/viewtopic.php?t=49199

avariant 18.04.2023 00:37

Я не понимаю, как я могу настроить wxButton во что-то вроде того, что я сделал (см. изображение), а вы?

user13170084 18.04.2023 00:47

@ user13170084, по какой причине вы не можете использовать для этого wxButton? т.е. - какой функционал из wxButton вам не нужен и что есть в обычной wxPanel?

Igor 18.04.2023 16:04

@Igor, если вместо этого я использую wxButton, как бы я изменил размер кнопки по умолчанию, ее цвет и так далее? не могу найти документацию по этому поводу...

user13170084 18.04.2023 19:45
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
7
58
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

В этом коде есть 2 большие проблемы:

  1. Вы вообще не должны использовать wxClientDC, см. примечание в его документации. Просто вызовите Refresh(), чтобы перерисовать окно.
  2. Вы должны захватить мышь при реагировании на события нажатия мыши, иначе у вас будут проблемы, если пользователь нажмет кнопку внутри окна и отпустит ее за его пределами (без захвата вы не получите последнее событие совсем).

Могут быть и другие проблемы, которых я не заметил, но вам нужно исправить хотя бы эти.

Другие вопросы по теме